Auto merge of #51278 - EPashkin:fix_mod_with_multilevel_paths_on_windows, r=nikomatsakis

Fix processing mod with multi-level path on Windows

Fix error in [rustfmt](https://github.com/rust-lang-nursery/rustfmt/issues/1754) because libsyntax can not handle `mod` with multilevel path on Windows.

Alternative is do almost same in https://github.com/rust-lang/rust/blob/master/src/libstd/sys/windows/fs.rs#L717 to allow work on paths with different separators, Ex. "\\\\?\\c:\\windows/temp"
diff --git a/.travis.yml b/.travis.yml
index 9e62b89..2e6722c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -284,6 +284,9 @@
       -exec head -750 {} \;
       -exec echo travis_fold":"end:crashlog \; || true
 
+  # see #50887
+  - head -30 ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
+
   # attempt to debug anything killed by the oom killer on linux, just to see if
   # it happened
   - dmesg | grep -i kill
@@ -301,7 +304,6 @@
           rm -rf obj/build/dist/doc &&
           cp -r obj/build/dist/* deploy/$TRAVIS_COMMIT;
       fi
-  - travis_retry gem update --system
   - ls -la deploy/$TRAVIS_COMMIT
 
 deploy:
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e7041dc..ea9f2c1 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -48,7 +48,7 @@
 extra credit. We won't mind if you accidentally file a duplicate report.
 
 Similarly, to help others who encountered the bug find your issue,
-consider filing an issue with with a descriptive title, which contains information that might be unique to it.
+consider filing an issue with a descriptive title, which contains information that might be unique to it.
 This can be the language or compiler feature used, the conditions that trigger the bug,
 or part of the error message if there is any.
 An example could be: **"impossible case reached" on lifetime inference for impl Trait in return position**.
@@ -142,7 +142,7 @@
 ### Building
 [building]: #building
 
-A default configuration shall use around 3.5 GB of disk space, whereas building a debug configuration may require more than 30 GB.
+A default configuration requires around 3.5 GB of disk space, whereas building a debug configuration may require more than 30 GB.
 
 Dependencies
 - [build dependencies](README.md#building-from-source)
diff --git a/README.md b/README.md
index 0481676..da678882 100644
--- a/README.md
+++ b/README.md
@@ -120,7 +120,7 @@
 > python x.py build
 ```
 
-Currently building Rust only works with some known versions of Visual Studio. If
+Currently, building Rust only works with some known versions of Visual Studio. If
 you have a more recent version installed the build system doesn't understand
 then you may need to force rustbuild to use an older version. This can be done
 by manually calling the appropriate vcvars file before running the bootstrap.
@@ -134,7 +134,7 @@
 [specifying-an-abi]: #specifying-an-abi
 
 Each specific ABI can also be used from either environment (for example, using
-the GNU ABI in powershell) by using an explicit build triple. The available
+the GNU ABI in PowerShell) by using an explicit build triple. The available
 Windows build triples are:
 - GNU ABI (using GCC)
     - `i686-pc-windows-gnu`
@@ -180,7 +180,7 @@
 [notes]: #notes
 
 Since the Rust compiler is written in Rust, it must be built by a
-precompiled "snapshot" version of itself (made in an earlier state of
+precompiled "snapshot" version of itself (made in an earlier stage of
 development). As such, source builds require a connection to the Internet, to
 fetch snapshots, and an OS that can execute the available snapshot binaries.
 
diff --git a/RELEASES.md b/RELEASES.md
index 758de62..9c501dc 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,161 @@
+Version 1.27.0 (2018-06-21)
+==========================
+
+Language
+--------
+- [Removed 'proc' from the reserved keywords list.][49699] This allows `proc` to
+  be used as an identifer.
+- [The dyn syntax is now available.][49968] This syntax is equivalent to the
+  bare `Trait` syntax, and should make it clearer when being used in tandem with
+  `impl Trait`. Since it is equivalent to the following syntax:
+  `&Trait == &dyn Trait`, `&mut Trait == &mut dyn Trait`, and
+  `Box<Trait> == Box<dyn Trait>`.
+- [Attributes on generic parameters such as types and lifetimes are
+  now stable.][48851] e.g.
+  `fn foo<#[lifetime_attr] 'a, #[type_attr] T: 'a>() {}`
+- [The `#[must_use]` attribute can now also be used on functions as well as
+  types.][48925] It provides a lint that by default warns users when the
+  value returned by a function has not been used.
+
+Compiler
+--------
+- [Added the `armv5te-unknown-linux-musl` target.][50423]
+
+Libraries
+---------
+- [SIMD (Single Instruction Multiple Data) on x86/x86_64 is now stable.][49664]
+  This includes [`arch::x86`] & [`arch::x86_64`] modules which contain
+  SIMD intrinsics, a new macro called `is_x86_feature_detected!`, the
+  `#[target_feature(enable="")]` attribute, and adding `target_feature = ""` to
+  the `cfg` attribute.
+- [A lot of methods for `[u8]`, `f32`, and `f64` previously only available in
+  std are now available in core.][49896]
+- [The generic `Rhs` type parameter on `ops::{Shl, ShlAssign, Shr}` now defaults
+  to `Self`.][49630]
+- [`std::str::replace` now has the `#[must_use]` attribute][50177] to clarify
+  that the operation isn't done in place.
+- [`Clone::clone`, `Iterator::collect`, and `ToOwned::to_owned` now have
+  the `#[must_use]` attribute][49533] to warn about unused potentially
+  expensive allocations.
+
+Stabilized APIs
+---------------
+- [`DoubleEndedIterator::rfind`]
+- [`DoubleEndedIterator::rfold`]
+- [`DoubleEndedIterator::try_rfold`]
+- [`Duration::from_micros`]
+- [`Duration::from_nanos`]
+- [`Duration::subsec_micros`]
+- [`Duration::subsec_millis`]
+- [`HashMap::remove_entry`]
+- [`Iterator::try_fold`]
+- [`Iterator::try_for_each`]
+- [`NonNull::cast`]
+- [`Option::filter`]
+- [`String::replace_range`]
+- [`Take::set_limit`]
+- [`hint::unreachable_unchecked`]
+- [`os::unix::process::parent_id`]
+- [`process::id`]
+- [`ptr::swap_nonoverlapping`]
+- [`slice::rsplit_mut`]
+- [`slice::rsplit`]
+- [`slice::swap_with_slice`]
+
+Cargo
+-----
+- [`cargo-metadata` now includes `authors`, `categories`, `keywords`,
+  `readme`, and `repository` fields.][cargo/5386]
+- [Added the `--target-dir` optional argument.][cargo/5393] This allows you to specify
+  a different directory than `target` for placing compilation artifacts.
+- [Cargo will be adding automatic target inference for binaries, benchmarks,
+  examples, and tests in the Rust 2018 edition.][cargo/5335] If your project specifies
+  specific targets e.g. using `[[bin]]` and have other binaries in locations
+  where cargo would infer a binary, Cargo will produce a warning. You can
+  disable this feature ahead of time by setting any of the following `autobins`,
+  `autobenches`, `autoexamples`, `autotests` to false.
+- [Cargo will now cache compiler information.][cargo/5359] This can be disabled by
+  setting `CARGO_CACHE_RUSTC_INFO=0` in your environment.
+
+Misc
+----
+- [Added “The Rustc book” into the official documentation.][49707]
+  [“The Rustc book”] documents and teaches how to use the rustc compiler.
+- [All books available on `doc.rust-lang.org` are now searchable.][49623]
+
+Compatibility Notes
+-------------------
+- [Calling a `CharExt` or `StrExt` method directly on core will no longer
+  work.][49896] e.g. `::core::prelude::v1::StrExt::is_empty("")` will not
+  compile, `"".is_empty()` will still compile.
+- [`Debug` output on `atomic::{AtomicBool, AtomicIsize, AtomicPtr, AtomicUsize}`
+  will only print the inner type.][48553] e.g.
+  `print!("{:?}", AtomicBool::new(true))` will print `true`
+  not `AtomicBool(true)`.
+- [The maximum number for `repr(align(N))` is now 2²⁹.][50378] Previously you
+  could enter higher numbers but they were not supported by LLVM. Up to 512MB
+  alignment should cover all use cases.
+
+[48553]: https://github.com/rust-lang/rust/pull/48553/
+[48851]: https://github.com/rust-lang/rust/pull/48851/
+[48925]: https://github.com/rust-lang/rust/pull/48925/
+[49533]: https://github.com/rust-lang/rust/pull/49533/
+[49623]: https://github.com/rust-lang/rust/pull/49623/
+[49630]: https://github.com/rust-lang/rust/pull/49630/
+[49664]: https://github.com/rust-lang/rust/pull/49664/
+[49699]: https://github.com/rust-lang/rust/pull/49699/
+[49707]: https://github.com/rust-lang/rust/pull/49707/
+[49719]: https://github.com/rust-lang/rust/pull/49719/
+[49896]: https://github.com/rust-lang/rust/pull/49896/
+[49968]: https://github.com/rust-lang/rust/pull/49968/
+[50177]: https://github.com/rust-lang/rust/pull/50177/
+[50378]: https://github.com/rust-lang/rust/pull/50378/
+[50398]: https://github.com/rust-lang/rust/pull/50398/
+[50423]: https://github.com/rust-lang/rust/pull/50423/
+[cargo/5203]: https://github.com/rust-lang/cargo/pull/5203/
+[cargo/5335]: https://github.com/rust-lang/cargo/pull/5335/
+[cargo/5359]: https://github.com/rust-lang/cargo/pull/5359/
+[cargo/5386]: https://github.com/rust-lang/cargo/pull/5386/
+[cargo/5393]: https://github.com/rust-lang/cargo/pull/5393/
+[`DoubleEndedIterator::rfind`]: https://doc.rust-lang.org/std/iter/trait.DoubleEndedIterator.html#method.rfind
+[`DoubleEndedIterator::rfold`]: https://doc.rust-lang.org/std/iter/trait.DoubleEndedIterator.html#method.rfold
+[`DoubleEndedIterator::try_rfold`]: https://doc.rust-lang.org/std/iter/trait.DoubleEndedIterator.html#method.try_rfold
+[`Duration::from_micros`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.from_micros
+[`Duration::from_nanos`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.from_nanos
+[`Duration::subsec_micros`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.subsec_micros
+[`Duration::subsec_millis`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.subsec_millis
+[`HashMap::remove_entry`]: https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.remove_entry
+[`Iterator::try_fold`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.try_fold
+[`Iterator::try_for_each`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.try_for_each
+[`NonNull::cast`]: https://doc.rust-lang.org/std/ptr/struct.NonNull.html#method.cast
+[`Option::filter`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.filter
+[`String::replace_range`]: https://doc.rust-lang.org/std/string/struct.String.html#method.replace_range
+[`Take::set_limit`]: https://doc.rust-lang.org/std/io/struct.Take.html#method.set_limit
+[`slice::rsplit_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rsplit_mut
+[`slice::rsplit`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rsplit
+[`slice::swap_with_slice`]: https://doc.rust-lang.org/std/primitive.slice.html#method.swap_with_slice
+[`arch::x86_64`]: https://doc.rust-lang.org/std/arch/x86_64/index.html
+[`arch::x86`]: https://doc.rust-lang.org/std/arch/x86/index.html
+[`fs::read`]:
+[`fs::write`]:
+[`hint::unreachable_unchecked`]: https://doc.rust-lang.org/std/hint/fn.unreachable_unchecked.html
+[`os::unix::process::parent_id`]: https://doc.rust-lang.org/std/os/unix/process/fn.parent_id.html
+[`ptr::swap_nonoverlapping`]: https://doc.rust-lang.org/std/ptr/fn.swap_nonoverlapping.html
+[`process::id`]: https://doc.rust-lang.org/std/process/fn.id.html
+[“The Rustc book”]: https://doc.rust-lang.org/rustc
+
+
+Version 1.26.2 (2018-06-05)
+==========================
+
+Compatibility Notes
+-------------------
+
+- [The borrow checker was fixed to avoid unsoundness when using match ergonomics][51117]
+
+[51117]: https://github.com/rust-lang/rust/issues/51117
+
+
 Version 1.26.1 (2018-05-29)
 ==========================
 
@@ -7,6 +165,7 @@
 - [RLS now works on Windows][50646]
 - [Rustfmt stopped badly formatting text in some cases][rustfmt/2695]
 
+
 Compatibility Notes
 --------
 
@@ -121,7 +280,6 @@
 - [Cargo will now output path to custom commands when `-v` is
   passed with `--list`][cargo/5041]
 - [The Cargo binary version is now the same as the Rust version][cargo/5083]
-- [`Cargo.lock` files are now included in published crates.][cargo/5093]
 
 Misc
 ----
@@ -225,7 +383,6 @@
 [`String::retain`]: https://doc.rust-lang.org/std/string/struct.String.html#method.retain
 [cargo/5041]: https://github.com/rust-lang/cargo/pull/5041
 [cargo/5083]: https://github.com/rust-lang/cargo/pull/5083
-[cargo/5093]: https://github.com/rust-lang/cargo/pull/5093
 
 
 Version 1.25.0 (2018-03-29)
diff --git a/config.toml.example b/config.toml.example
index 33ad914..5054a8f 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -279,6 +279,9 @@
 # Whether or not `panic!`s generate backtraces (RUST_BACKTRACE)
 #backtrace = true
 
+# Whether to always use incremental compilation when building rustc
+#incremental = false
+
 # Build rustc with experimental parallelization
 #experimental-parallel-queries = false
 
diff --git a/src/Cargo.lock b/src/Cargo.lock
index 3a27107..d4544ff 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -1456,10 +1456,11 @@
 
 [[package]]
 name = "polonius-engine"
-version = "0.4.0"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "datafrog 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1687,6 +1688,7 @@
  "clippy_lints 0.0.205 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "languageserver-types 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1698,10 +1700,10 @@
  "rls-analysis 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-blacklist 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-data 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rls-rustc 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rls-rustc 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-vfs 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustfmt-nightly 0.8.2",
+ "rustfmt-nightly 0.8.2 (git+https://github.com/rust-lang-nursery/rustfmt?rev=f3906267)",
  "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1740,7 +1742,7 @@
 
 [[package]]
 name = "rls-rustc"
-version = "0.3.0"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1785,12 +1787,16 @@
  "jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "polonius-engine 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "polonius-engine 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc_macro 0.0.0",
+ "rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_apfloat 0.0.0",
  "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
  "rustc_target 0.0.0",
+ "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "serialize 0.0.0",
  "syntax 0.0.0",
  "syntax_pos 0.0.0",
@@ -1799,15 +1805,32 @@
 
 [[package]]
 name = "rustc-ap-arena"
-version = "147.0.0"
+version = "149.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "rustc-ap-rustc_data_structures 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rustc-ap-arena"
+version = "156.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rustc-ap-rustc_data_structures 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_cratesio_shim"
-version = "147.0.0"
+version = "149.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rustc-ap-rustc_cratesio_shim"
+version = "156.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1816,7 +1839,7 @@
 
 [[package]]
 name = "rustc-ap-rustc_data_structures"
-version = "147.0.0"
+version = "149.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1824,65 +1847,139 @@
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_cratesio_shim 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_cratesio_shim 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-rayon 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rustc-ap-rustc_data_structures"
+version = "156.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ena 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_cratesio_shim 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_errors"
-version = "147.0.0"
+version = "149.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax_pos 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax_pos 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rustc-ap-rustc_errors"
+version = "156.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax_pos 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_target"
-version = "147.0.0"
+version = "149.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_cratesio_shim 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_cratesio_shim 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rustc-ap-rustc_target"
+version = "156.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_cratesio_shim 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-serialize"
-version = "147.0.0"
+version = "149.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "rustc-ap-serialize"
+version = "156.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "rustc-ap-syntax"
-version = "147.0.0"
+version = "149.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_errors 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_target 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax_pos 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_errors 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_target 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax_pos 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rustc-ap-syntax"
+version = "156.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_errors 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_target 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax_pos 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-syntax_pos"
-version = "147.0.0"
+version = "149.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "rustc-ap-arena 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-arena 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rustc-ap-syntax_pos"
+version = "156.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rustc-ap-arena 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1910,16 +2007,16 @@
 
 [[package]]
 name = "rustc-rayon"
-version = "0.1.0"
+version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-rayon-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-rayon-core"
-version = "0.1.0"
+version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2043,7 +2140,8 @@
  "parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-rayon 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_cratesio_shim 0.0.0",
  "serialize 0.0.0",
  "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2059,7 +2157,7 @@
  "graphviz 0.0.0",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
- "rustc-rayon 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_allocator 0.0.0",
  "rustc_borrowck 0.0.0",
  "rustc_codegen_utils 0.0.0",
@@ -2173,7 +2271,7 @@
  "graphviz 0.0.0",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log_settings 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "polonius-engine 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "polonius-engine 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_apfloat 0.0.0",
  "rustc_data_structures 0.0.0",
@@ -2305,7 +2403,6 @@
 version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
- "fmt_macros 0.0.0",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
@@ -2359,6 +2456,31 @@
 [[package]]
 name = "rustfmt-nightly"
 version = "0.8.2"
+source = "git+https://github.com/rust-lang-nursery/rustfmt?rev=f3906267#f390626778c1bbb13911556d585850eb2fa67923"
+dependencies = [
+ "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "derive-new 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "isatty 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_target 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rustfmt-nightly"
+version = "0.8.2"
 dependencies = [
  "assert_cli 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2372,8 +2494,8 @@
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_target 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_target 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3175,7 +3297,7 @@
 "checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03"
 "checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2"
 "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
-"checksum polonius-engine 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9385a6d8f8ff6fd7e48a803c6a77fb89cc929dc7e2af6bf972494bbc8ff8b9e4"
+"checksum polonius-engine 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b6b0a7f5f4278b991ffd14abce1d01b013121ad297460237ef0a2f08d43201"
 "checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
 "checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6"
 "checksum proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "49b6a521dc81b643e9a51e0d1cf05df46d5a2f3c0280ea72bcb68276ba64a118"
@@ -3200,24 +3322,33 @@
 "checksum rls-analysis 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "da9794cd1f80f2cb888c00641a32f9855d0226c954ee31cef145784914c7142e"
 "checksum rls-blacklist 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e4a9cc2545ccb7e05b355bfe047b8039a6ec12270d5f3c996b766b340a50f7d2"
 "checksum rls-data 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3dd20763e1c60ae8945384c8a8fa4ac44f8afa7b0a817511f5e8927e5d24f988"
-"checksum rls-rustc 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ed5342b2bbbe8663c04600af506c8902b6b4d3e627b006eb1bd65aa14805f4d"
+"checksum rls-rustc 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2c8c09117ae2887baaa4b17fe1cb572f9b22e4d2c6a5cda04093d8b366b0be99"
 "checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a"
 "checksum rls-vfs 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "be231e1e559c315bc60ced5ad2cc2d7a9c208ed7d4e2c126500149836fda19bb"
-"checksum rustc-ap-arena 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1304956fbbdd070e4478672d040f0453374604a12a0938aaba4b38a2bd124667"
-"checksum rustc-ap-rustc_cratesio_shim 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d1dcd0fafa3c7875b76e33feaf69b332870180475ba3eb8dd003bcc2a2dc069"
-"checksum rustc-ap-rustc_data_structures 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "76c1a3fe4a0104b922ffc8080bd7c703dc20f2874b7c982638f6adb6c378b77a"
-"checksum rustc-ap-rustc_errors 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2812e295d2930bf3b3c22dbe8ef0bb8ae98a497ae6ad379d0709434387a9004b"
-"checksum rustc-ap-rustc_target 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5bd371121f16da666f6d6d5e6ff57cd972cc8206cc80377ba411b99607d49cbd"
-"checksum rustc-ap-serialize 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bde493c1c16d724e42536117c385b69f2eae9b2ec38bab841c45373bce4a9d8f"
-"checksum rustc-ap-syntax 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "402c1f402e6d47defcd884d3f715aaa8c6f2cbdd5f13cb06fea70486d512426b"
-"checksum rustc-ap-syntax_pos 147.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb707a229093791dc3fc35aca61d9bf0e3708f23da4536683527857bc624b061"
+"checksum rustc-ap-arena 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e794b25832224eea9252ebfa9f94ab7070d0a60c977793112c611501cb56b48d"
+"checksum rustc-ap-arena 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83e91a01cd6c5a9e4f68c2b5c81b62b172aa9e00fc2fec862c0899e3fac1fd32"
+"checksum rustc-ap-rustc_cratesio_shim 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a78241b2ecb82ebb9221b4b7d37c024ff1f2e43f1b099f38a997f030fc7894b0"
+"checksum rustc-ap-rustc_cratesio_shim 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1e8ea8fadc5d66c1527771816e83f7e7599543bd2e1583e279855370ab2f18e5"
+"checksum rustc-ap-rustc_data_structures 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5529c3927f32b0b56d1f6449a34f2218dc2160c6a6dde0cf47954d83a9a45764"
+"checksum rustc-ap-rustc_data_structures 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "742ba74bc7d0f3ded56148329650f137fa5b90f7f0ecc4b4952150f32c66b147"
+"checksum rustc-ap-rustc_errors 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb1fef44a7d63f5d204c981adb26a14e85fe7ee5962050a4f664df6f425f9b48"
+"checksum rustc-ap-rustc_errors 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3714046c6f8c1c259822aefcca21b1862710a6cec24fd34c0796117f074c6769"
+"checksum rustc-ap-rustc_target 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a3939a9f7bf063536dd646894ca43b1378ec6a56ac5b2698cc6ba0b42bfadbdc"
+"checksum rustc-ap-rustc_target 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b982c4517c18080895b06149ce8aa8279fd013f629030bb7a179bfcff6d74ef2"
+"checksum rustc-ap-serialize 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "692169d0bac8a4547f9778039460799e162664477a1eaec15d31507705f8c736"
+"checksum rustc-ap-serialize 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "27c7700595bff1a64ddb6f593c69db3f6d66b76b059b26137236c7e21e36db70"
+"checksum rustc-ap-syntax 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "22e93ee3817b007d56b5c5b151e6cd7c7063455a1facaf9e0ca01f9d9365b716"
+"checksum rustc-ap-syntax 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e6482d98c8be57d3cfe55dab744dd1a87f8462dc2ea0a8a4960f7bb1565be049"
+"checksum rustc-ap-syntax_pos 149.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fe5d24a137d6e202cd6eb96cb74f8cb4a2b257c42b74dd624e136b4e19f0a47d"
+"checksum rustc-ap-syntax_pos 156.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "20af5e200b61a3e5ba4f58ed3cbd7593569faf8f0956d5233f4f27fee51b4c81"
 "checksum rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11fb43a206a04116ffd7cfcf9bcb941f8eb6cc7ff667272246b0a1c74259a3cb"
 "checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8"
-"checksum rustc-rayon 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1aa5cd8c3a706edb19b6ec6aa7b056bdc635b6e99c5cf7014f9af9d92f15e99"
-"checksum rustc-rayon-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d69983f8613a9c3ba1a3bbf5e8bdf2fd5c42317b1d8dd8623ca8030173bf8a6b"
+"checksum rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c6d5a683c6ba4ed37959097e88d71c9e8e26659a3cb5be8b389078e7ad45306"
+"checksum rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40f06724db71e18d68b3b946fdf890ca8c921d9edccc1404fdfdb537b0d12649"
 "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
 "checksum rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a54aa04a10c68c1c4eacb4337fd883b435997ede17a9385784b990777686b09a"
 "checksum rustfix 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9da3cf9b79dc889a2c9879643f26d7a53e37e9361c7566b7d2787d5ace0d8396"
+"checksum rustfmt-nightly 0.8.2 (git+https://github.com/rust-lang-nursery/rustfmt?rev=f3906267)" = "<none>"
 "checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637"
 "checksum schannel 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "85fd9df495640643ad2d00443b3d78aae69802ad488debab4f1dd52fc1806ade"
 "checksum scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8674d439c964889e2476f474a3bf198cc9e199e77499960893bac5de7e9218a4"
diff --git a/src/README.md b/src/README.md
index 690ab67..6da4944 100644
--- a/src/README.md
+++ b/src/README.md
@@ -6,7 +6,7 @@
 For more information on how various parts of the compiler work, see the [rustc guide].
 
 Their is also useful content in the following READMEs, which are gradually being moved over to the guide:
-- https://github.com/rust-lang/rust/tree/master/src/librustc/ty/maps
+- https://github.com/rust-lang/rust/tree/master/src/librustc/ty/query
 - https://github.com/rust-lang/rust/tree/master/src/librustc/dep_graph
 - https://github.com/rust-lang/rust/blob/master/src/librustc/infer/region_constraints
 - https://github.com/rust-lang/rust/tree/master/src/librustc/infer/higher_ranked
diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index 6f27402..4607ca5 100644
--- a/src/bootstrap/bin/rustc.rs
+++ b/src/bootstrap/bin/rustc.rs
@@ -268,6 +268,15 @@
         if let Ok(host_linker) = env::var("RUSTC_HOST_LINKER") {
             cmd.arg(format!("-Clinker={}", host_linker));
         }
+
+        if let Ok(s) = env::var("RUSTC_HOST_CRT_STATIC") {
+            if s == "true" {
+                cmd.arg("-C").arg("target-feature=+crt-static");
+            }
+            if s == "false" {
+                cmd.arg("-C").arg("target-feature=-crt-static");
+            }
+        }
     }
 
     if env::var_os("RUSTC_PARALLEL_QUERIES").is_some() {
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 487440b..28f5192 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -489,7 +489,7 @@
         """
         return os.path.join(self.build_dir, self.build, "stage0")
 
-    def get_toml(self, key):
+    def get_toml(self, key, section=None):
         """Returns the value of the given key in config.toml, otherwise returns None
 
         >>> rb = RustBuild()
@@ -501,12 +501,29 @@
 
         >>> rb.get_toml("key3") is None
         True
+
+        Optionally also matches the section the key appears in
+
+        >>> rb.config_toml = '[a]\\nkey = "value1"\\n[b]\\nkey = "value2"'
+        >>> rb.get_toml('key', 'a')
+        'value1'
+        >>> rb.get_toml('key', 'b')
+        'value2'
+        >>> rb.get_toml('key', 'c') is None
+        True
         """
+
+        cur_section = None
         for line in self.config_toml.splitlines():
+            section_match = re.match(r'^\s*\[(.*)\]\s*$', line)
+            if section_match is not None:
+                cur_section = section_match.group(1)
+
             match = re.match(r'^{}\s*=(.*)$'.format(key), line)
             if match is not None:
                 value = match.group(1)
-                return self.get_string(value) or value.strip()
+                if section is None or section == cur_section:
+                    return self.get_string(value) or value.strip()
         return None
 
     def cargo(self):
@@ -589,7 +606,17 @@
         env["LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib") + \
             (os.pathsep + env["LIBRARY_PATH"]) \
             if "LIBRARY_PATH" in env else ""
-        env["RUSTFLAGS"] = "-Cdebuginfo=2"
+        env["RUSTFLAGS"] = "-Cdebuginfo=2 "
+
+        build_section = "target.{}".format(self.build_triple())
+        target_features = []
+        if self.get_toml("crt-static", build_section) == "true":
+            target_features += ["+crt-static"]
+        elif self.get_toml("crt-static", build_section) == "false":
+            target_features += ["-crt-static"]
+        if target_features:
+            env["RUSTFLAGS"] += "-C target-feature=" + (",".join(target_features)) + " "
+
         env["PATH"] = os.path.join(self.bin_root(), "bin") + \
             os.pathsep + env["PATH"]
         if not os.path.isfile(self.cargo()):
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 4fdb36b..ec7eebd 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -339,6 +339,7 @@
                 compile::Std,
                 compile::Test,
                 compile::Rustc,
+                compile::CodegenBackend,
                 compile::StartupObjects,
                 tool::BuildManifest,
                 tool::Rustbook,
@@ -369,7 +370,6 @@
             ),
             Kind::Test => describe!(
                 test::Tidy,
-                test::Bootstrap,
                 test::Ui,
                 test::RunPass,
                 test::CompileFail,
@@ -415,6 +415,8 @@
                 test::Clippy,
                 test::RustdocJS,
                 test::RustdocTheme,
+                // Run bootstrap close to the end as it's unlikely to fail
+                test::Bootstrap,
                 // Run run-make last, since these won't pass without make on Windows
                 test::RunMake,
                 test::RustdocUi
@@ -698,9 +700,14 @@
         let out_dir = self.stage_out(compiler, mode);
         cargo
             .env("CARGO_TARGET_DIR", out_dir)
-            .arg(cmd)
-            .arg("--target")
-            .arg(target);
+            .arg(cmd);
+
+        if cmd != "install" {
+            cargo.arg("--target")
+                 .arg(target);
+        } else {
+            assert_eq!(target, compiler.host);
+        }
 
         // Set a flag for `check` so that certain build scripts can do less work
         // (e.g. not building/requiring LLVM).
@@ -795,13 +802,10 @@
             cargo.env("RUSTC_ERROR_FORMAT", error_format);
         }
         if cmd != "build" && cmd != "check" && want_rustdoc {
-            cargo.env(
-                "RUSTDOC_LIBDIR",
-                self.rustc_libdir(self.compiler(2, self.config.build)),
-            );
+            cargo.env("RUSTDOC_LIBDIR", self.sysroot_libdir(compiler, self.config.build));
         }
 
-        if mode == Mode::Tool {
+        if mode.is_tool() {
             // Tools like cargo and rls don't get debuginfo by default right now, but this can be
             // enabled in the config.  Adding debuginfo makes them several times larger.
             if self.config.rust_debuginfo_tools {
@@ -842,6 +846,10 @@
             cargo.env("RUSTC_CRT_STATIC", x.to_string());
         }
 
+        if let Some(x) = self.crt_static(compiler.host) {
+            cargo.env("RUSTC_HOST_CRT_STATIC", x.to_string());
+        }
+
         // Enable usage of unstable features
         cargo.env("RUSTC_BOOTSTRAP", "1");
         self.add_rust_test_threads(&mut cargo);
@@ -862,7 +870,7 @@
         //
         // If LLVM support is disabled we need to use the snapshot compiler to compile
         // build scripts, as the new compiler doesn't support executables.
-        if mode == Mode::Libstd || !self.config.llvm_enabled {
+        if mode == Mode::Std || !self.config.llvm_enabled {
             cargo
                 .env("RUSTC_SNAPSHOT", &self.initial_rustc)
                 .env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_snapshot_libdir());
@@ -894,7 +902,7 @@
         cargo.env("RUSTC_VERBOSE", format!("{}", self.verbosity));
 
         // in std, we want to avoid denying warnings for stage 0 as that makes cfg's painful.
-        if self.config.deny_warnings && !(mode == Mode::Libstd && stage == 0) {
+        if self.config.deny_warnings && !(mode == Mode::Std && stage == 0) {
             cargo.env("RUSTC_DENY_WARNINGS", "1");
         }
 
@@ -954,7 +962,7 @@
         }
 
         if cmd == "build"
-            && mode == Mode::Libstd
+            && mode == Mode::Std
             && self.config.extended
             && compiler.is_final_stage(self)
         {
@@ -1003,7 +1011,7 @@
         // be resolved because MinGW has the import library. The downside is we
         // don't get newer functions from Windows, but we don't use any of them
         // anyway.
-        if mode != Mode::Tool {
+        if !mode.is_tool() {
             cargo.env("WINAPI_NO_BUNDLED_LIBRARIES", "1");
         }
 
@@ -1018,8 +1026,8 @@
         }
 
         if self.config.rust_optimize {
-            // FIXME: cargo bench does not accept `--release`
-            if cmd != "bench" {
+            // FIXME: cargo bench/install do not accept `--release`
+            if cmd != "bench" && cmd != "install" {
                 cargo.arg("--release");
             }
         }
@@ -1742,7 +1750,7 @@
             &[test::Crate {
                 compiler: Compiler { host, stage: 0 },
                 target: host,
-                mode: Mode::Libstd,
+                mode: Mode::Std,
                 test_kind: test::TestKind::Test,
                 krate: INTERNER.intern_str("std"),
             },]
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index a516af5..b3ccb3c 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -40,10 +40,10 @@
         let target = self.target;
         let compiler = builder.compiler(0, builder.config.build);
 
-        let out_dir = builder.stage_out(compiler, Mode::Libstd);
+        let out_dir = builder.stage_out(compiler, Mode::Std);
         builder.clear_if_dirty(&out_dir, &builder.rustc(compiler));
 
-        let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "check");
+        let mut cargo = builder.cargo(compiler, Mode::Std, target, "check");
         std_cargo(builder, &compiler, target, &mut cargo);
 
         let _folder = builder.fold_output(|| format!("stage{}-std", compiler.stage));
@@ -87,11 +87,11 @@
         let compiler = builder.compiler(0, builder.config.build);
         let target = self.target;
 
-        let stage_out = builder.stage_out(compiler, Mode::Librustc);
+        let stage_out = builder.stage_out(compiler, Mode::Rustc);
         builder.clear_if_dirty(&stage_out, &libstd_stamp(builder, compiler, target));
         builder.clear_if_dirty(&stage_out, &libtest_stamp(builder, compiler, target));
 
-        let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "check");
+        let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "check");
         rustc_cargo(builder, &mut cargo);
 
         let _folder = builder.fold_output(|| format!("stage{}-rustc", compiler.stage));
@@ -137,7 +137,7 @@
         let target = self.target;
         let backend = self.backend;
 
-        let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "check");
+        let mut cargo = builder.cargo(compiler, Mode::Codegen, target, "check");
         let features = builder.rustc_features().to_string();
         cargo.arg("--manifest-path").arg(builder.src.join("src/librustc_codegen_llvm/Cargo.toml"));
         rustc_cargo_env(builder, &mut cargo);
@@ -175,10 +175,10 @@
         let compiler = builder.compiler(0, builder.config.build);
         let target = self.target;
 
-        let out_dir = builder.stage_out(compiler, Mode::Libtest);
+        let out_dir = builder.stage_out(compiler, Mode::Test);
         builder.clear_if_dirty(&out_dir, &libstd_stamp(builder, compiler, target));
 
-        let mut cargo = builder.cargo(compiler, Mode::Libtest, target, "check");
+        let mut cargo = builder.cargo(compiler, Mode::Test, target, "check");
         test_cargo(builder, &compiler, target, &mut cargo);
 
         let _folder = builder.fold_output(|| format!("stage{}-test", compiler.stage));
@@ -219,6 +219,7 @@
 
         let mut cargo = prepare_tool_cargo(builder,
                                            compiler,
+                                           Mode::ToolRustc,
                                            target,
                                            "check",
                                            "src/tools/rustdoc");
@@ -236,7 +237,7 @@
         builder.ensure(tool::CleanTools {
             compiler,
             target,
-            mode: Mode::Tool,
+            cause: Mode::Rustc,
         });
     }
 }
@@ -244,19 +245,19 @@
 /// Cargo's output path for the standard library in a given stage, compiled
 /// by a particular compiler for the specified target.
 pub fn libstd_stamp(builder: &Builder, compiler: Compiler, target: Interned<String>) -> PathBuf {
-    builder.cargo_out(compiler, Mode::Libstd, target).join(".libstd-check.stamp")
+    builder.cargo_out(compiler, Mode::Std, target).join(".libstd-check.stamp")
 }
 
 /// Cargo's output path for libtest in a given stage, compiled by a particular
 /// compiler for the specified target.
 pub fn libtest_stamp(builder: &Builder, compiler: Compiler, target: Interned<String>) -> PathBuf {
-    builder.cargo_out(compiler, Mode::Libtest, target).join(".libtest-check.stamp")
+    builder.cargo_out(compiler, Mode::Test, target).join(".libtest-check.stamp")
 }
 
 /// Cargo's output path for librustc in a given stage, compiled by a particular
 /// compiler for the specified target.
 pub fn librustc_stamp(builder: &Builder, compiler: Compiler, target: Interned<String>) -> PathBuf {
-    builder.cargo_out(compiler, Mode::Librustc, target).join(".librustc-check.stamp")
+    builder.cargo_out(compiler, Mode::Rustc, target).join(".librustc-check.stamp")
 }
 
 /// Cargo's output path for librustc_codegen_llvm in a given stage, compiled by a particular
@@ -265,12 +266,12 @@
                          compiler: Compiler,
                          target: Interned<String>,
                          backend: Interned<String>) -> PathBuf {
-    builder.cargo_out(compiler, Mode::Librustc, target)
+    builder.cargo_out(compiler, Mode::Codegen, target)
          .join(format!(".librustc_codegen_llvm-{}-check.stamp", backend))
 }
 
 /// Cargo's output path for rustdoc in a given stage, compiled by a particular
 /// compiler for the specified target.
 pub fn rustdoc_stamp(builder: &Builder, compiler: Compiler, target: Interned<String>) -> PathBuf {
-    builder.cargo_out(compiler, Mode::Tool, target).join(".rustdoc-check.stamp")
+    builder.cargo_out(compiler, Mode::ToolRustc, target).join(".rustdoc-check.stamp")
 }
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 231ed9d..11d9154 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -98,9 +98,9 @@
             copy_musl_third_party_objects(builder, target, &libdir);
         }
 
-        let out_dir = builder.cargo_out(compiler, Mode::Libstd, target);
+        let out_dir = builder.cargo_out(compiler, Mode::Std, target);
         builder.clear_if_dirty(&out_dir, &builder.rustc(compiler));
-        let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "build");
+        let mut cargo = builder.cargo(compiler, Mode::Std, target, "build");
         std_cargo(builder, &compiler, target, &mut cargo);
 
         let _folder = builder.fold_output(|| format!("stage{}-std", compiler.stage));
@@ -240,7 +240,7 @@
         builder.ensure(tool::CleanTools {
             compiler: target_compiler,
             target,
-            mode: Mode::Libstd,
+            cause: Mode::Std,
         });
     }
 }
@@ -368,9 +368,9 @@
             return;
         }
 
-        let out_dir = builder.cargo_out(compiler, Mode::Libtest, target);
+        let out_dir = builder.cargo_out(compiler, Mode::Test, target);
         builder.clear_if_dirty(&out_dir, &libstd_stamp(builder, compiler, target));
-        let mut cargo = builder.cargo(compiler, Mode::Libtest, target, "build");
+        let mut cargo = builder.cargo(compiler, Mode::Test, target, "build");
         test_cargo(builder, &compiler, target, &mut cargo);
 
         let _folder = builder.fold_output(|| format!("stage{}-test", compiler.stage));
@@ -431,7 +431,7 @@
         builder.ensure(tool::CleanTools {
             compiler: target_compiler,
             target,
-            mode: Mode::Libtest,
+            cause: Mode::Test,
         });
     }
 }
@@ -489,11 +489,11 @@
             compiler: builder.compiler(self.compiler.stage, builder.config.build),
             target: builder.config.build,
         });
-        let cargo_out = builder.cargo_out(compiler, Mode::Librustc, target);
+        let cargo_out = builder.cargo_out(compiler, Mode::Rustc, target);
         builder.clear_if_dirty(&cargo_out, &libstd_stamp(builder, compiler, target));
         builder.clear_if_dirty(&cargo_out, &libtest_stamp(builder, compiler, target));
 
-        let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "build");
+        let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "build");
         rustc_cargo(builder, &mut cargo);
 
         let _folder = builder.fold_output(|| format!("stage{}-rustc", compiler.stage));
@@ -585,7 +585,7 @@
         builder.ensure(tool::CleanTools {
             compiler: target_compiler,
             target,
-            mode: Mode::Librustc,
+            cause: Mode::Rustc,
         });
     }
 }
@@ -634,7 +634,7 @@
             return;
         }
 
-        let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "build");
+        let mut cargo = builder.cargo(compiler, Mode::Codegen, target, "build");
         let mut features = builder.rustc_features().to_string();
         cargo.arg("--manifest-path")
             .arg(builder.src.join("src/librustc_codegen_llvm/Cargo.toml"));
@@ -642,7 +642,7 @@
 
         features += &build_codegen_backend(&builder, &mut cargo, &compiler, target, backend);
 
-        let tmp_stamp = builder.cargo_out(compiler, Mode::Librustc, target)
+        let tmp_stamp = builder.cargo_out(compiler, Mode::Codegen, target)
             .join(".tmp.stamp");
 
         let _folder = builder.fold_output(|| format!("stage{}-rustc_codegen_llvm", compiler.stage));
@@ -793,19 +793,19 @@
 /// Cargo's output path for the standard library in a given stage, compiled
 /// by a particular compiler for the specified target.
 pub fn libstd_stamp(builder: &Builder, compiler: Compiler, target: Interned<String>) -> PathBuf {
-    builder.cargo_out(compiler, Mode::Libstd, target).join(".libstd.stamp")
+    builder.cargo_out(compiler, Mode::Std, target).join(".libstd.stamp")
 }
 
 /// Cargo's output path for libtest in a given stage, compiled by a particular
 /// compiler for the specified target.
 pub fn libtest_stamp(builder: &Builder, compiler: Compiler, target: Interned<String>) -> PathBuf {
-    builder.cargo_out(compiler, Mode::Libtest, target).join(".libtest.stamp")
+    builder.cargo_out(compiler, Mode::Test, target).join(".libtest.stamp")
 }
 
 /// Cargo's output path for librustc in a given stage, compiled by a particular
 /// compiler for the specified target.
 pub fn librustc_stamp(builder: &Builder, compiler: Compiler, target: Interned<String>) -> PathBuf {
-    builder.cargo_out(compiler, Mode::Librustc, target).join(".librustc.stamp")
+    builder.cargo_out(compiler, Mode::Rustc, target).join(".librustc.stamp")
 }
 
 /// Cargo's output path for librustc_codegen_llvm in a given stage, compiled by a particular
@@ -814,7 +814,7 @@
                          compiler: Compiler,
                          target: Interned<String>,
                          backend: Interned<String>) -> PathBuf {
-    builder.cargo_out(compiler, Mode::Librustc, target)
+    builder.cargo_out(compiler, Mode::Codegen, target)
         .join(format!(".librustc_codegen_llvm-{}.stamp", backend))
 }
 
@@ -971,7 +971,7 @@
         }
 
         // Link the compiler binary itself into place
-        let out_dir = builder.cargo_out(build_compiler, Mode::Librustc, host);
+        let out_dir = builder.cargo_out(build_compiler, Mode::Rustc, host);
         let rustc = out_dir.join(exe("rustc_binary", &*host));
         let bindir = sysroot.join("bin");
         t!(fs::create_dir_all(&bindir));
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 9840682..47feb8a 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -303,6 +303,7 @@
     dist_src: Option<bool>,
     quiet_tests: Option<bool>,
     test_miri: Option<bool>,
+    incremental: Option<bool>,
     save_toolstates: Option<String>,
     codegen_backends: Option<Vec<String>>,
     codegen_backends_dir: Option<String>,
@@ -529,6 +530,10 @@
             set(&mut config.rust_dist_src, rust.dist_src);
             set(&mut config.quiet_tests, rust.quiet_tests);
             set(&mut config.test_miri, rust.test_miri);
+            // in the case "false" is set explicitly, do not overwrite the command line args
+            if let Some(true) = rust.incremental {
+                config.incremental = true;
+            }
             set(&mut config.wasm_syscall, rust.wasm_syscall);
             set(&mut config.lld_enabled, rust.lld);
             config.rustc_parallel_queries = rust.experimental_parallel_queries.unwrap_or(false);
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index e21a593..7341137 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -722,7 +722,7 @@
 
         let image = tmpdir(builder).join(format!("{}-{}-image", name, target));
 
-        let src = builder.stage_out(compiler, Mode::Libstd)
+        let src = builder.stage_out(compiler, Mode::Std)
             .join(target).join(builder.cargo_dir()).join("deps");
 
         let image_src = src.join("save-analysis");
@@ -951,13 +951,16 @@
                 has_cargo_vendor |= line.starts_with("cargo-vendor ");
             }
             if !has_cargo_vendor {
-                let mut cmd = Command::new(&builder.initial_cargo);
-                cmd.arg("install")
-                   .arg("--force")
+                let mut cmd = builder.cargo(
+                    builder.compiler(0, builder.config.build),
+                    Mode::ToolRustc,
+                    builder.config.build,
+                    "install"
+                );
+                cmd.arg("--force")
                    .arg("--debug")
                    .arg("--vers").arg(CARGO_VENDOR_VERSION)
-                   .arg("cargo-vendor")
-                   .env("RUSTC", &builder.initial_rustc);
+                   .arg("cargo-vendor");
                 if let Some(dir) = builder.openssl_install_dir(builder.config.build) {
                     builder.ensure(native::Openssl {
                         target: builder.config.build,
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index cb22993..19599b3 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -463,7 +463,7 @@
         };
 
         builder.ensure(compile::Std { compiler, target });
-        let out_dir = builder.stage_out(compiler, Mode::Libstd)
+        let out_dir = builder.stage_out(compiler, Mode::Std)
                            .join(target).join("doc");
 
         // Here what we're doing is creating a *symlink* (directory junction on
@@ -483,7 +483,7 @@
         builder.clear_if_dirty(&my_out, &rustdoc);
         t!(symlink_dir_force(&builder.config, &my_out, &out_dir));
 
-        let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "doc");
+        let mut cargo = builder.cargo(compiler, Mode::Std, target, "doc");
         compile::std_cargo(builder, &compiler, target, &mut cargo);
 
         // Keep a whitelist so we do not build internal stdlib crates, these will be
@@ -546,7 +546,7 @@
         builder.ensure(Std { stage, target });
 
         builder.ensure(compile::Test { compiler, target });
-        let out_dir = builder.stage_out(compiler, Mode::Libtest)
+        let out_dir = builder.stage_out(compiler, Mode::Test)
                            .join(target).join("doc");
 
         // See docs in std above for why we symlink
@@ -554,7 +554,7 @@
         builder.clear_if_dirty(&my_out, &rustdoc);
         t!(symlink_dir_force(&builder.config, &my_out, &out_dir));
 
-        let mut cargo = builder.cargo(compiler, Mode::Libtest, target, "doc");
+        let mut cargo = builder.cargo(compiler, Mode::Test, target, "doc");
         compile::test_cargo(builder, &compiler, target, &mut cargo);
 
         cargo.arg("--no-deps").arg("-p").arg("test");
@@ -614,7 +614,7 @@
         builder.ensure(Std { stage, target });
 
         builder.ensure(compile::Rustc { compiler, target });
-        let out_dir = builder.stage_out(compiler, Mode::Librustc)
+        let out_dir = builder.stage_out(compiler, Mode::Rustc)
                            .join(target).join("doc");
 
         // See docs in std above for why we symlink
@@ -622,7 +622,7 @@
         builder.clear_if_dirty(&my_out, &rustdoc);
         t!(symlink_dir_force(&builder.config, &my_out, &out_dir));
 
-        let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc");
+        let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "doc");
         compile::rustc_cargo(builder, &mut cargo);
 
         // We don't want to build docs for internal compiler dependencies in this
@@ -698,12 +698,12 @@
 
         // We do not symlink to the same shared folder that already contains std library
         // documentation from previous steps as we do not want to include that.
-        let out_dir = builder.stage_out(compiler, Mode::Librustc).join(target).join("doc");
+        let out_dir = builder.stage_out(compiler, Mode::Rustc).join(target).join("doc");
         builder.clear_if_dirty(&out, &rustdoc);
         t!(symlink_dir_force(&builder.config, &out, &out_dir));
 
         // Build cargo command.
-        let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc");
+        let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "doc");
         cargo.env("RUSTDOCFLAGS", "--document-private-items");
         compile::rustc_cargo(builder, &mut cargo);
 
@@ -799,13 +799,15 @@
         builder.ensure(tool::Rustdoc { host: compiler.host });
 
         // Symlink compiler docs to the output directory of rustdoc documentation.
-        let out_dir = builder.stage_out(compiler, Mode::Tool).join(target).join("doc");
+        let out_dir = builder.stage_out(compiler, Mode::ToolRustc).join(target).join("doc");
         t!(fs::create_dir_all(&out_dir));
         builder.clear_if_dirty(&out, &rustdoc);
         t!(symlink_dir_force(&builder.config, &out, &out_dir));
 
         // Build cargo command.
-        let mut cargo = prepare_tool_cargo(builder, compiler, target, "doc", "src/tools/rustdoc");
+        let mut cargo = prepare_tool_cargo(
+            builder, compiler, Mode::ToolRustc, target, "doc", "src/tools/rustdoc");
+
         cargo.env("RUSTDOCFLAGS", "--document-private-items");
         builder.run(&mut cargo);
     }
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index f64161f..6e77413 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -280,7 +280,8 @@
 struct Crate {
     name: Interned<String>,
     version: String,
-    deps: Vec<Interned<String>>,
+    deps: HashSet<Interned<String>>,
+    id: String,
     path: PathBuf,
     doc_step: String,
     build_step: String,
@@ -307,16 +308,30 @@
 #[derive(Debug, Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 pub enum Mode {
     /// Build the standard library, placing output in the "stageN-std" directory.
-    Libstd,
+    Std,
 
     /// Build libtest, placing output in the "stageN-test" directory.
-    Libtest,
+    Test,
 
-    /// Build librustc and compiler libraries, placing output in the "stageN-rustc" directory.
-    Librustc,
+    /// Build librustc, and compiler libraries, placing output in the "stageN-rustc" directory.
+    Rustc,
 
-    /// Build some tool, placing output in the "stageN-tools" directory.
-    Tool,
+    /// Build codegen libraries, placing output in the "stageN-codegen" directory
+    Codegen,
+
+    /// Build some tools, placing output in the "stageN-tools" directory.
+    ToolStd,
+    ToolTest,
+    ToolRustc,
+}
+
+impl Mode {
+    pub fn is_tool(&self) -> bool {
+        match self {
+            Mode::ToolStd | Mode::ToolTest | Mode::ToolRustc => true,
+            _ => false
+        }
+    }
 }
 
 impl Build {
@@ -517,10 +532,11 @@
     /// The mode indicates what the root directory is for.
     fn stage_out(&self, compiler: Compiler, mode: Mode) -> PathBuf {
         let suffix = match mode {
-            Mode::Libstd => "-std",
-            Mode::Libtest => "-test",
-            Mode::Tool => "-tools",
-            Mode::Librustc => "-rustc",
+            Mode::Std => "-std",
+            Mode::Test => "-test",
+            Mode::Codegen => "-rustc",
+            Mode::Rustc => "-rustc",
+            Mode::ToolStd | Mode::ToolTest | Mode::ToolRustc => "-tools",
         };
         self.out.join(&*compiler.host)
                 .join(format!("stage{}{}", compiler.stage, suffix))
diff --git a/src/bootstrap/metadata.rs b/src/bootstrap/metadata.rs
index 5f1df1d..718a6da 100644
--- a/src/bootstrap/metadata.rs
+++ b/src/bootstrap/metadata.rs
@@ -11,6 +11,7 @@
 use std::collections::HashMap;
 use std::process::Command;
 use std::path::PathBuf;
+use std::collections::HashSet;
 
 use build_helper::output;
 use serde_json;
@@ -45,45 +46,17 @@
 }
 
 pub fn build(build: &mut Build) {
-    build_krate(build, "src/libstd");
-    build_krate(build, "src/libtest");
-    build_krate(build, "src/rustc");
-}
+    let mut resolves = Vec::new();
+    build_krate(&build.std_features(), build, &mut resolves, "src/libstd");
+    build_krate("", build, &mut resolves, "src/libtest");
+    build_krate(&build.rustc_features(), build, &mut resolves, "src/rustc");
 
-fn build_krate(build: &mut Build, krate: &str) {
-    // Run `cargo metadata` to figure out what crates we're testing.
-    //
-    // Down below we're going to call `cargo test`, but to test the right set
-    // of packages we're going to have to know what `-p` arguments to pass it
-    // to know what crates to test. Here we run `cargo metadata` to learn about
-    // the dependency graph and what `-p` arguments there are.
-    let mut cargo = Command::new(&build.initial_cargo);
-    cargo.arg("metadata")
-         .arg("--format-version").arg("1")
-         .arg("--manifest-path").arg(build.src.join(krate).join("Cargo.toml"));
-    let output = output(&mut cargo);
-    let output: Output = serde_json::from_str(&output).unwrap();
     let mut id2name = HashMap::new();
-    for package in output.packages {
-        if package.source.is_none() {
-            let name = INTERNER.intern_string(package.name);
-            id2name.insert(package.id, name);
-            let mut path = PathBuf::from(package.manifest_path);
-            path.pop();
-            build.crates.insert(name, Crate {
-                build_step: format!("build-crate-{}", name),
-                doc_step: format!("doc-crate-{}", name),
-                test_step: format!("test-crate-{}", name),
-                bench_step: format!("bench-crate-{}", name),
-                name,
-                version: package.version,
-                deps: Vec::new(),
-                path,
-            });
-        }
+    for (name, krate) in build.crates.iter() {
+        id2name.insert(krate.id.clone(), name.clone());
     }
 
-    for node in output.resolve.nodes {
+    for node in resolves {
         let name = match id2name.get(&node.id) {
             Some(name) => name,
             None => continue,
@@ -95,7 +68,42 @@
                 Some(dep) => dep,
                 None => continue,
             };
-            krate.deps.push(*dep);
+            krate.deps.insert(*dep);
         }
     }
 }
+
+fn build_krate(features: &str, build: &mut Build, resolves: &mut Vec<ResolveNode>, krate: &str) {
+    // Run `cargo metadata` to figure out what crates we're testing.
+    //
+    // Down below we're going to call `cargo test`, but to test the right set
+    // of packages we're going to have to know what `-p` arguments to pass it
+    // to know what crates to test. Here we run `cargo metadata` to learn about
+    // the dependency graph and what `-p` arguments there are.
+    let mut cargo = Command::new(&build.initial_cargo);
+    cargo.arg("metadata")
+         .arg("--format-version").arg("1")
+         .arg("--features").arg(features)
+         .arg("--manifest-path").arg(build.src.join(krate).join("Cargo.toml"));
+    let output = output(&mut cargo);
+    let output: Output = serde_json::from_str(&output).unwrap();
+    for package in output.packages {
+        if package.source.is_none() {
+            let name = INTERNER.intern_string(package.name);
+            let mut path = PathBuf::from(package.manifest_path);
+            path.pop();
+            build.crates.insert(name, Crate {
+                build_step: format!("build-crate-{}", name),
+                doc_step: format!("doc-crate-{}", name),
+                test_step: format!("test-crate-{}", name),
+                bench_step: format!("bench-crate-{}", name),
+                name,
+                version: package.version,
+                id: package.id,
+                deps: HashSet::new(),
+                path,
+            });
+        }
+    }
+    resolves.extend(output.resolve.nodes);
+}
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 9284778..ce6506b 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -222,7 +222,7 @@
             compiler,
             target: self.host,
         });
-        let mut cargo = builder.cargo(compiler, Mode::Tool, self.host, "test");
+        let mut cargo = builder.cargo(compiler, Mode::ToolRustc, self.host, "test");
         cargo
             .arg("--manifest-path")
             .arg(builder.src.join("src/tools/cargo/Cargo.toml"));
@@ -281,7 +281,12 @@
             return;
         }
 
-        let mut cargo = tool::prepare_tool_cargo(builder, compiler, host, "test", "src/tools/rls");
+        let mut cargo = tool::prepare_tool_cargo(builder,
+                                                 compiler,
+                                                 Mode::ToolRustc,
+                                                 host,
+                                                 "test",
+                                                 "src/tools/rls");
 
         // Don't build tests dynamically, just a pain to work with
         cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
@@ -331,8 +336,12 @@
             return;
         }
 
-        let mut cargo =
-            tool::prepare_tool_cargo(builder, compiler, host, "test", "src/tools/rustfmt");
+        let mut cargo = tool::prepare_tool_cargo(builder,
+                                                 compiler,
+                                                 Mode::ToolRustc,
+                                                 host,
+                                                 "test",
+                                                 "src/tools/rustfmt");
 
         // Don't build tests dynamically, just a pain to work with
         cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
@@ -383,7 +392,7 @@
             extra_features: Vec::new(),
         });
         if let Some(miri) = miri {
-            let mut cargo = builder.cargo(compiler, Mode::Tool, host, "test");
+            let mut cargo = builder.cargo(compiler, Mode::ToolRustc, host, "test");
             cargo
                 .arg("--manifest-path")
                 .arg(builder.src.join("src/tools/miri/Cargo.toml"));
@@ -441,7 +450,7 @@
             extra_features: Vec::new(),
         });
         if let Some(clippy) = clippy {
-            let mut cargo = builder.cargo(compiler, Mode::Tool, host, "test");
+            let mut cargo = builder.cargo(compiler, Mode::ToolRustc, host, "test");
             cargo
                 .arg("--manifest-path")
                 .arg(builder.src.join("src/tools/clippy/Cargo.toml"));
@@ -453,7 +462,7 @@
             cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler));
             cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler));
             let host_libs = builder
-                .stage_out(compiler, Mode::Tool)
+                .stage_out(compiler, Mode::ToolRustc)
                 .join(builder.cargo_dir());
             cargo.env("HOST_LIBS", host_libs);
             // clippy tests need to find the driver
@@ -952,8 +961,7 @@
         if suite.ends_with("fulldeps") ||
             // FIXME: Does pretty need librustc compiled? Note that there are
             // fulldeps test suites with mode = pretty as well.
-            mode == "pretty" ||
-            mode == "rustdoc"
+            mode == "pretty"
         {
             builder.ensure(compile::Rustc { compiler, target });
         }
@@ -1435,7 +1443,7 @@
         builder.ensure(Crate {
             compiler: self.compiler,
             target: self.target,
-            mode: Mode::Librustc,
+            mode: Mode::Rustc,
             test_kind: self.test_kind,
             krate: self.krate,
         });
@@ -1486,7 +1494,7 @@
         builder.ensure(Crate {
             compiler: self.compiler,
             target: self.target,
-            mode: Mode::Libstd,
+            mode: Mode::Std,
             test_kind: self.test_kind,
             krate: INTERNER.intern_str(self.krate),
         });
@@ -1539,12 +1547,12 @@
 
         for krate in builder.in_tree_crates("std") {
             if run.path.ends_with(&krate.local_path(&builder)) {
-                make(Mode::Libstd, krate);
+                make(Mode::Std, krate);
             }
         }
         for krate in builder.in_tree_crates("test") {
             if run.path.ends_with(&krate.local_path(&builder)) {
-                make(Mode::Libtest, krate);
+                make(Mode::Test, krate);
             }
         }
     }
@@ -1579,13 +1587,13 @@
 
         let mut cargo = builder.cargo(compiler, mode, target, test_kind.subcommand());
         match mode {
-            Mode::Libstd => {
+            Mode::Std => {
                 compile::std_cargo(builder, &compiler, target, &mut cargo);
             }
-            Mode::Libtest => {
+            Mode::Test => {
                 compile::test_cargo(builder, &compiler, target, &mut cargo);
             }
-            Mode::Librustc => {
+            Mode::Rustc => {
                 builder.ensure(compile::Rustc { compiler, target });
                 compile::rustc_cargo(builder, &mut cargo);
             }
@@ -1719,13 +1727,12 @@
         let compiler = builder.compiler(builder.top_stage, self.host);
         let target = compiler.host;
 
-        let mut cargo = tool::prepare_tool_cargo(
-            builder,
-            compiler,
-            target,
-            test_kind.subcommand(),
-            "src/tools/rustdoc",
-        );
+        let mut cargo = tool::prepare_tool_cargo(builder,
+                                                 compiler,
+                                                 Mode::ToolRustc,
+                                                 target,
+                                                 test_kind.subcommand(),
+                                                 "src/tools/rustdoc");
         if test_kind.subcommand() == "test" && !builder.fail_fast {
             cargo.arg("--no-fail-fast");
         }
@@ -1914,6 +1921,9 @@
             cmd.arg("--no-fail-fast");
         }
         cmd.arg("--").args(&builder.config.cmd.test_args());
+        // rustbuild tests are racy on directory creation so just run them one at a time.
+        // Since there's not many this shouldn't be a problem.
+        cmd.arg("--test-threads=1");
         try_run(builder, &mut cmd);
     }
 
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index 29f37b3..0c164d8 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -28,7 +28,7 @@
 pub struct CleanTools {
     pub compiler: Compiler,
     pub target: Interned<String>,
-    pub mode: Mode,
+    pub cause: Mode,
 }
 
 impl Step for CleanTools {
@@ -41,23 +41,23 @@
     fn run(self, builder: &Builder) {
         let compiler = self.compiler;
         let target = self.target;
-        let mode = self.mode;
+        let cause = self.cause;
 
         // This is for the original compiler, but if we're forced to use stage 1, then
         // std/test/rustc stamps won't exist in stage 2, so we need to get those from stage 1, since
         // we copy the libs forward.
-        let tools_dir = builder.stage_out(compiler, Mode::Tool);
+        let tools_dir = builder.stage_out(compiler, Mode::ToolRustc);
         let compiler = if builder.force_use_stage1(compiler, target) {
             builder.compiler(1, compiler.host)
         } else {
             compiler
         };
 
-        for &cur_mode in &[Mode::Libstd, Mode::Libtest, Mode::Librustc] {
+        for &cur_mode in &[Mode::Std, Mode::Test, Mode::Rustc] {
             let stamp = match cur_mode {
-                Mode::Libstd => libstd_stamp(builder, compiler, target),
-                Mode::Libtest => libtest_stamp(builder, compiler, target),
-                Mode::Librustc => librustc_stamp(builder, compiler, target),
+                Mode::Std => libstd_stamp(builder, compiler, target),
+                Mode::Test => libtest_stamp(builder, compiler, target),
+                Mode::Rustc => librustc_stamp(builder, compiler, target),
                 _ => panic!(),
             };
 
@@ -67,7 +67,7 @@
 
             // If we are a rustc tool, and std changed, we also need to clear ourselves out -- our
             // dependencies depend on std. Therefore, we iterate up until our own mode.
-            if mode == cur_mode {
+            if cause == cur_mode {
                 break;
             }
         }
@@ -104,13 +104,13 @@
         let is_ext_tool = self.is_ext_tool;
 
         match self.mode {
-            Mode::Libstd => builder.ensure(compile::Std { compiler, target }),
-            Mode::Libtest => builder.ensure(compile::Test { compiler, target }),
-            Mode::Librustc => builder.ensure(compile::Rustc { compiler, target }),
-            Mode::Tool => panic!("unexpected Mode::Tool for tool build")
+            Mode::ToolStd => builder.ensure(compile::Std { compiler, target }),
+            Mode::ToolTest => builder.ensure(compile::Test { compiler, target }),
+            Mode::ToolRustc => builder.ensure(compile::Rustc { compiler, target }),
+            _ => panic!("unexpected Mode for tool build")
         }
 
-        let mut cargo = prepare_tool_cargo(builder, compiler, target, "build", path);
+        let mut cargo = prepare_tool_cargo(builder, compiler, self.mode, target, "build", path);
         cargo.arg("--features").arg(self.extra_features.join(" "));
 
         let _folder = builder.fold_output(|| format!("stage{}-{}", compiler.stage, tool));
@@ -202,7 +202,7 @@
                 return None;
             }
         } else {
-            let cargo_out = builder.cargo_out(compiler, Mode::Tool, target)
+            let cargo_out = builder.cargo_out(compiler, self.mode, target)
                 .join(exe(tool, &compiler.host));
             let bin = builder.tools_dir(compiler).join(exe(tool, &compiler.host));
             builder.copy(&cargo_out, &bin);
@@ -214,11 +214,12 @@
 pub fn prepare_tool_cargo(
     builder: &Builder,
     compiler: Compiler,
+    mode: Mode,
     target: Interned<String>,
     command: &'static str,
     path: &'static str,
 ) -> Command {
-    let mut cargo = builder.cargo(compiler, Mode::Tool, target, command);
+    let mut cargo = builder.cargo(compiler, mode, target, command);
     let dir = builder.src.join(path);
     cargo.arg("--manifest-path").arg(dir.join("Cargo.toml"));
 
@@ -253,7 +254,7 @@
 }
 
 macro_rules! tool {
-    ($($name:ident, $path:expr, $tool_name:expr, $mode:expr;)+) => {
+    ($($name:ident, $path:expr, $tool_name:expr, $mode:expr $(,llvm_tools = $llvm:expr)*;)+) => {
         #[derive(Copy, Clone)]
         pub enum Tool {
             $(
@@ -261,6 +262,22 @@
             )+
         }
 
+        impl Tool {
+            pub fn get_mode(&self) -> Mode {
+                let mode = match self {
+                    $(Tool::$name => $mode,)+
+                };
+                mode
+            }
+
+            /// Whether this tool requires LLVM to run
+            pub fn uses_llvm_tools(&self) -> bool {
+                match self {
+                    $(Tool::$name => true $(&& $llvm)*,)+
+                }
+            }
+        }
+
         impl<'a> Builder<'a> {
             pub fn tool_exe(&self, tool: Tool) -> PathBuf {
                 let stage = self.tool_default_stage(tool);
@@ -323,18 +340,21 @@
     }
 }
 
+// FIXME(#51459): We have only checked that RustInstaller does not require
+// the LLVM binaries when running. We should go through all tools to determine
+// if they really need LLVM binaries, and make `llvm_tools` a required argument.
 tool!(
-    Rustbook, "src/tools/rustbook", "rustbook", Mode::Librustc;
-    ErrorIndex, "src/tools/error_index_generator", "error_index_generator", Mode::Librustc;
-    UnstableBookGen, "src/tools/unstable-book-gen", "unstable-book-gen", Mode::Libstd;
-    Tidy, "src/tools/tidy", "tidy", Mode::Libstd;
-    Linkchecker, "src/tools/linkchecker", "linkchecker", Mode::Libstd;
-    CargoTest, "src/tools/cargotest", "cargotest", Mode::Libstd;
-    Compiletest, "src/tools/compiletest", "compiletest", Mode::Libtest;
-    BuildManifest, "src/tools/build-manifest", "build-manifest", Mode::Libstd;
-    RemoteTestClient, "src/tools/remote-test-client", "remote-test-client", Mode::Libstd;
-    RustInstaller, "src/tools/rust-installer", "fabricate", Mode::Libstd;
-    RustdocTheme, "src/tools/rustdoc-themes", "rustdoc-themes", Mode::Libstd;
+    Rustbook, "src/tools/rustbook", "rustbook", Mode::ToolRustc;
+    ErrorIndex, "src/tools/error_index_generator", "error_index_generator", Mode::ToolRustc;
+    UnstableBookGen, "src/tools/unstable-book-gen", "unstable-book-gen", Mode::ToolStd;
+    Tidy, "src/tools/tidy", "tidy", Mode::ToolStd;
+    Linkchecker, "src/tools/linkchecker", "linkchecker", Mode::ToolStd;
+    CargoTest, "src/tools/cargotest", "cargotest", Mode::ToolStd;
+    Compiletest, "src/tools/compiletest", "compiletest", Mode::ToolTest;
+    BuildManifest, "src/tools/build-manifest", "build-manifest", Mode::ToolStd;
+    RemoteTestClient, "src/tools/remote-test-client", "remote-test-client", Mode::ToolStd;
+    RustInstaller, "src/tools/rust-installer", "fabricate", Mode::ToolStd, llvm_tools = false;
+    RustdocTheme, "src/tools/rustdoc-themes", "rustdoc-themes", Mode::ToolStd;
 );
 
 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
@@ -362,7 +382,7 @@
             compiler: self.compiler,
             target: self.target,
             tool: "remote-test-server",
-            mode: Mode::Libstd,
+            mode: Mode::ToolStd,
             path: "src/tools/remote-test-server",
             is_ext_tool: false,
             extra_features: Vec::new(),
@@ -414,6 +434,7 @@
 
         let mut cargo = prepare_tool_cargo(builder,
                                            build_compiler,
+                                           Mode::ToolRustc,
                                            target,
                                            "build",
                                            "src/tools/rustdoc");
@@ -430,7 +451,7 @@
         // Cargo adds a number of paths to the dylib search path on windows, which results in
         // the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool"
         // rustdoc a different name.
-        let tool_rustdoc = builder.cargo_out(build_compiler, Mode::Tool, target)
+        let tool_rustdoc = builder.cargo_out(build_compiler, Mode::ToolRustc, target)
             .join(exe("rustdoc_tool_binary", &target_compiler.host));
 
         // don't create a stage0-sysroot/bin directory.
@@ -485,7 +506,7 @@
             compiler: self.compiler,
             target: self.target,
             tool: "cargo",
-            mode: Mode::Librustc,
+            mode: Mode::ToolRustc,
             path: "src/tools/cargo",
             is_ext_tool: false,
             extra_features: Vec::new(),
@@ -533,7 +554,7 @@
                     compiler: $sel.compiler,
                     target: $sel.target,
                     tool: $tool_name,
-                    mode: Mode::Librustc,
+                    mode: Mode::ToolRustc,
                     path: $path,
                     extra_features: $sel.extra_features,
                     is_ext_tool: true,
@@ -575,7 +596,7 @@
     pub fn tool_cmd(&self, tool: Tool) -> Command {
         let mut cmd = Command::new(self.tool_exe(tool));
         let compiler = self.compiler(self.tool_default_stage(tool), self.config.build);
-        self.prepare_tool_cmd(compiler, &mut cmd);
+        self.prepare_tool_cmd(compiler, tool, &mut cmd);
         cmd
     }
 
@@ -583,11 +604,11 @@
     ///
     /// Notably this munges the dynamic library lookup path to point to the
     /// right location to run `compiler`.
-    fn prepare_tool_cmd(&self, compiler: Compiler, cmd: &mut Command) {
+    fn prepare_tool_cmd(&self, compiler: Compiler, tool: Tool, cmd: &mut Command) {
         let host = &compiler.host;
         let mut lib_paths: Vec<PathBuf> = vec![
             PathBuf::from(&self.sysroot_libdir(compiler, compiler.host)),
-            self.cargo_out(compiler, Mode::Tool, *host).join("deps"),
+            self.cargo_out(compiler, tool.get_mode(), *host).join("deps"),
         ];
 
         // On MSVC a tool may invoke a C compiler (e.g. compiletest in run-make
@@ -610,17 +631,19 @@
 
         // Add the llvm/bin directory to PATH since it contains lots of
         // useful, platform-independent tools
-        if let Some(llvm_bin_path) = self.llvm_bin_path() {
-            if host.contains("windows") {
-                // On Windows, PATH and the dynamic library path are the same,
-                // so we just add the LLVM bin path to lib_path
-                lib_paths.push(llvm_bin_path);
-            } else {
-                let old_path = env::var_os("PATH").unwrap_or_default();
-                let new_path = env::join_paths(iter::once(llvm_bin_path)
-                        .chain(env::split_paths(&old_path)))
-                    .expect("Could not add LLVM bin path to PATH");
-                cmd.env("PATH", new_path);
+        if tool.uses_llvm_tools() {
+            if let Some(llvm_bin_path) = self.llvm_bin_path() {
+                if host.contains("windows") {
+                    // On Windows, PATH and the dynamic library path are the same,
+                    // so we just add the LLVM bin path to lib_path
+                    lib_paths.push(llvm_bin_path);
+                } else {
+                    let old_path = env::var_os("PATH").unwrap_or_default();
+                    let new_path = env::join_paths(iter::once(llvm_bin_path)
+                            .chain(env::split_paths(&old_path)))
+                        .expect("Could not add LLVM bin path to PATH");
+                    cmd.env("PATH", new_path);
+                }
             }
         }
 
diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh
index 3465e38..8913fda 100755
--- a/src/ci/docker/run.sh
+++ b/src/ci/docker/run.sh
@@ -118,6 +118,10 @@
 # goes ahead and sets it for all builders.
 args="$args --privileged"
 
+if [ "$CI" != "" ]; then
+    args="$args --dns 8.8.8.8 --dns 8.8.4.4 --dns 1.1.1.1 --dns 1.0.0.1"
+fi
+
 exec docker \
   run \
   --volume "$root_dir:/checkout:ro" \
diff --git a/src/ci/docker/x86_64-gnu-tools/checkregression.py b/src/ci/docker/x86_64-gnu-tools/checkregression.py
index df791d1..208aab4 100755
--- a/src/ci/docker/x86_64-gnu-tools/checkregression.py
+++ b/src/ci/docker/x86_64-gnu-tools/checkregression.py
@@ -18,6 +18,7 @@
     os_name = sys.argv[1]
     toolstate_file = sys.argv[2]
     current_state = sys.argv[3]
+    verb = sys.argv[4] # 'regressed' or 'changed'
 
     with open(toolstate_file, 'r') as f:
         toolstate = json.load(f)
@@ -29,10 +30,17 @@
         tool = cur['tool']
         state = cur[os_name]
         new_state = toolstate.get(tool, '')
-        if new_state < state:
+        if verb == 'regressed':
+            updated = new_state < state
+        elif verb == 'changed':
+            updated = new_state != state
+        else:
+            print('Unknown verb {}'.format(updated))
+            sys.exit(2)
+        if updated:
             print(
-                'Error: The state of "{}" has regressed from "{}" to "{}"'
-                .format(tool, state, new_state)
+                'The state of "{}" has {} from "{}" to "{}"'
+                .format(tool, verb, state, new_state)
             )
             regressed = True
 
diff --git a/src/ci/docker/x86_64-gnu-tools/checktools.sh b/src/ci/docker/x86_64-gnu-tools/checktools.sh
index d71d5da..56e6372 100755
--- a/src/ci/docker/x86_64-gnu-tools/checktools.sh
+++ b/src/ci/docker/x86_64-gnu-tools/checktools.sh
@@ -91,19 +91,26 @@
 
 status_check "submodule_changed"
 
+CHECK_NOT="$(readlink -f "$(dirname $0)/checkregression.py")"
+change_toolstate() {
+    # only update the history
+    if python2.7 "$CHECK_NOT" "$OS" "$TOOLSTATE_FILE" "_data/latest.json" changed; then
+        echo 'Toolstate is not changed. Not updating.'
+    else
+        if [ $SIX_WEEK_CYCLE -eq 5 ]; then
+            python2.7 "$CHECK_NOT" "$OS" "$TOOLSTATE_FILE" "_data/latest.json" regressed
+        fi
+        sed -i "1 a\\
+$COMMIT\t$(cat "$TOOLSTATE_FILE")
+" "history/$OS.tsv"
+    fi
+}
+
 if [ "$RUST_RELEASE_CHANNEL" = nightly -a -n "${TOOLSTATE_REPO_ACCESS_TOKEN+is_set}" ]; then
     . "$(dirname $0)/repo.sh"
     MESSAGE_FILE=$(mktemp -t msg.XXXXXX)
     echo "($OS CI update)" > "$MESSAGE_FILE"
-    commit_toolstate_change "$MESSAGE_FILE" \
-        sed -i "1 a\\
-$COMMIT\t$(cat "$TOOLSTATE_FILE")
-" "history/$OS.tsv"
-    # if we are at the last week in the 6-week release cycle, reject any kind of regression.
-    if [ $SIX_WEEK_CYCLE -eq 5 ]; then
-        python2.7 "$(dirname $0)/checkregression.py" \
-            "$OS" "$TOOLSTATE_FILE" "rust-toolstate/_data/latest.json"
-    fi
+    commit_toolstate_change "$MESSAGE_FILE" change_toolstate
     rm -f "$MESSAGE_FILE"
     exit 0
 fi
diff --git a/src/doc/rustdoc/src/documentation-tests.md b/src/doc/rustdoc/src/documentation-tests.md
index fd7d171..cb233cc 100644
--- a/src/doc/rustdoc/src/documentation-tests.md
+++ b/src/doc/rustdoc/src/documentation-tests.md
@@ -79,8 +79,9 @@
 an example block that looks like this:
 
 ```text
-/// Some documentation.
-# fn foo() {}
+/// /// Some documentation.
+/// # fn foo() {} // this function will be hidden
+/// println!("Hello, World!");
 ```
 
 It will render like this:
@@ -88,6 +89,7 @@
 ```rust
 /// Some documentation.
 # fn foo() {}
+println!("Hello, World!");
 ```
 
 Yes, that's right: you can add lines that start with `# `, and they will
@@ -168,37 +170,56 @@
 compiles, while only showing the parts that are relevant to that part of your
 explanation.
 
-Another case where the use of `#` is handy is when you want to ignore
-error handling. Lets say you want the following,
+
+## Using `?` in doc tests
+
+When writing an example, it is rarely useful to include a complete error
+handling, as it would add significant amounts of boilerplate code. Instead, you
+may want the following:
 
 ```ignore
+/// ```
 /// use std::io;
 /// let mut input = String::new();
 /// io::stdin().read_line(&mut input)?;
+/// ```
 ```
 
-The problem is that `?` returns a `Result<T, E>` and test functions
-don't return anything so this will give a mismatched types error.
+The problem is that `?` returns a `Result<T, E>` and test functions don't
+return anything, so this will give a mismatched types error.
+
+You can get around this limitation by manually adding a `main` that returns
+`Result<T, E>`, because `Result<T, E>` implements the `Termination` trait:
 
 ```ignore
 /// A doc test using ?
 ///
 /// ```
 /// use std::io;
-/// # fn foo() -> io::Result<()> {
+///
+/// fn main() -> io::Result<()> {
+///     let mut input = String::new();
+///     io::stdin().read_line(&mut input)?;
+///     Ok(())
+/// }
+/// ```
+```
+
+Together with the `# ` from the section above, you arrive at a solution that
+appears to the reader as the initial idea but works with doc tests:
+
+```ignore
+/// ```
+/// use std::io;
+/// # fn main() -> io::Result<()> {
 /// let mut input = String::new();
 /// io::stdin().read_line(&mut input)?;
 /// # Ok(())
 /// # }
 /// ```
-# fn foo() {}
 ```
 
-You can get around this by wrapping the code in a function. This catches
-and swallows the `Result<T, E>` when running tests on the docs. This
-pattern appears regularly in the standard library.
-
-### Documenting macros
+## Documenting macros
 
 Here’s an example of documenting a macro:
 
diff --git a/src/doc/unstable-book/src/language-features/global-allocator.md b/src/doc/unstable-book/src/language-features/global-allocator.md
deleted file mode 100644
index 8f1ba22..0000000
--- a/src/doc/unstable-book/src/language-features/global-allocator.md
+++ /dev/null
@@ -1,72 +0,0 @@
-# `global_allocator`
-
-The tracking issue for this feature is: [#27389]
-
-[#27389]: https://github.com/rust-lang/rust/issues/27389
-
-------------------------
-
-Rust programs may need to change the allocator that they're running with from
-time to time. This use case is distinct from an allocator-per-collection (e.g. a
-`Vec` with a custom allocator) and instead is more related to changing the
-global default allocator, e.g. what `Vec<T>` uses by default.
-
-Currently Rust programs don't have a specified global allocator. The compiler
-may link to a version of [jemalloc] on some platforms, but this is not
-guaranteed. Libraries, however, like cdylibs and staticlibs are guaranteed
-to use the "system allocator" which means something like `malloc` on Unixes and
-`HeapAlloc` on Windows.
-
-[jemalloc]: https://github.com/jemalloc/jemalloc
-
-The `#[global_allocator]` attribute, however, allows configuring this choice.
-You can use this to implement a completely custom global allocator to route all
-default allocation requests to a custom object. Defined in [RFC 1974] usage
-looks like:
-
-[RFC 1974]: https://github.com/rust-lang/rfcs/pull/1974
-
-```rust
-#![feature(global_allocator, allocator_api, heap_api)]
-
-use std::alloc::{GlobalAlloc, System, Layout, Opaque};
-use std::ptr::NonNull;
-
-struct MyAllocator;
-
-unsafe impl GlobalAlloc for MyAllocator {
-    unsafe fn alloc(&self, layout: Layout) -> *mut Opaque {
-        System.alloc(layout)
-    }
-
-    unsafe fn dealloc(&self, ptr: *mut Opaque, layout: Layout) {
-        System.dealloc(ptr, layout)
-    }
-}
-
-#[global_allocator]
-static GLOBAL: MyAllocator = MyAllocator;
-
-fn main() {
-    // This `Vec` will allocate memory through `GLOBAL` above
-    let mut v = Vec::new();
-    v.push(1);
-}
-```
-
-And that's it! The `#[global_allocator]` attribute is applied to a `static`
-which implements the `Alloc` trait in the `std::alloc` module. Note, though,
-that the implementation is defined for `&MyAllocator`, not just `MyAllocator`.
-You may wish, however, to also provide `Alloc for MyAllocator` for other use
-cases.
-
-A crate can only have one instance of `#[global_allocator]` and this instance
-may be loaded through a dependency. For example `#[global_allocator]` above
-could have been placed in one of the dependencies loaded through `extern crate`.
-
-Note that `Alloc` itself is an `unsafe` trait, with much documentation on the
-trait itself about usage and for implementors. Extra care should be taken when
-implementing a global allocator as well as the allocator may be called from many
-portions of the standard library, such as the panicking routine. As a result it
-is highly recommended to not panic during allocation and work in as many
-situations with as few dependencies as possible as well.
diff --git a/src/doc/unstable-book/src/language-features/lang-items.md b/src/doc/unstable-book/src/language-features/lang-items.md
index 6a7aea7..bac619f 100644
--- a/src/doc/unstable-book/src/language-features/lang-items.md
+++ b/src/doc/unstable-book/src/language-features/lang-items.md
@@ -19,6 +19,7 @@
 #![feature(lang_items, box_syntax, start, libc, core_intrinsics)]
 #![no_std]
 use core::intrinsics;
+use core::panic::PanicInfo;
 
 extern crate libc;
 
@@ -50,7 +51,7 @@
 }
 
 #[lang = "eh_personality"] extern fn rust_eh_personality() {}
-#[lang = "panic_fmt"] extern fn rust_begin_panic() -> ! { unsafe { intrinsics::abort() } }
+#[lang = "panic_impl"] extern fn rust_begin_panic(info: &PanicInfo) -> ! { unsafe { intrinsics::abort() } }
 #[lang = "eh_unwind_resume"] extern fn rust_eh_unwind_resume() {}
 #[no_mangle] pub extern fn rust_eh_register_frames () {}
 #[no_mangle] pub extern fn rust_eh_unregister_frames () {}
@@ -110,6 +111,7 @@
 #![feature(start)]
 #![no_std]
 use core::intrinsics;
+use core::panic::PanicInfo;
 
 // Pull in the system libc library for what crt0.o likely requires.
 extern crate libc;
@@ -134,12 +136,9 @@
 pub extern fn rust_eh_unwind_resume() {
 }
 
-#[lang = "panic_fmt"]
+#[lang = "panic_impl"]
 #[no_mangle]
-pub extern fn rust_begin_panic(_msg: core::fmt::Arguments,
-                               _file: &'static str,
-                               _line: u32,
-                               _column: u32) -> ! {
+pub extern fn rust_begin_panic(info: &PanicInfo) -> ! {
     unsafe { intrinsics::abort() }
 }
 ```
@@ -155,6 +154,7 @@
 #![no_std]
 #![no_main]
 use core::intrinsics;
+use core::panic::PanicInfo;
 
 // Pull in the system libc library for what crt0.o likely requires.
 extern crate libc;
@@ -179,12 +179,9 @@
 pub extern fn rust_eh_unwind_resume() {
 }
 
-#[lang = "panic_fmt"]
+#[lang = "panic_impl"]
 #[no_mangle]
-pub extern fn rust_begin_panic(_msg: core::fmt::Arguments,
-                               _file: &'static str,
-                               _line: u32,
-                               _column: u32) -> ! {
+pub extern fn rust_begin_panic(info: &PanicInfo) -> ! {
     unsafe { intrinsics::abort() }
 }
 ```
@@ -215,7 +212,7 @@
 
 The second function, `rust_begin_panic`, is also used by the failure mechanisms of the
 compiler. When a panic happens, this controls the message that's displayed on
-the screen. While the language item's name is `panic_fmt`, the symbol name is
+the screen. While the language item's name is `panic_impl`, the symbol name is
 `rust_begin_panic`.
 
 A third function, `rust_eh_unwind_resume`, is also needed if the `custom_unwind_resume`
@@ -259,8 +256,8 @@
   - `msvc_try_filter`: `libpanic_unwind/seh.rs` (SEH)
   - `panic`: `libcore/panicking.rs`
   - `panic_bounds_check`: `libcore/panicking.rs`
-  - `panic_fmt`: `libcore/panicking.rs`
-  - `panic_fmt`: `libstd/panicking.rs`
+  - `panic_impl`: `libcore/panicking.rs`
+  - `panic_impl`: `libstd/panicking.rs`
 - Allocations
   - `owned_box`: `liballoc/boxed.rs`
   - `exchange_malloc`: `liballoc/heap.rs`
diff --git a/src/doc/unstable-book/src/language-features/repr-transparent.md b/src/doc/unstable-book/src/language-features/repr-transparent.md
deleted file mode 100644
index 62202dc..0000000
--- a/src/doc/unstable-book/src/language-features/repr-transparent.md
+++ /dev/null
@@ -1,176 +0,0 @@
-# `repr_transparent`
-
-The tracking issue for this feature is: [#43036]
-
-[#43036]: https://github.com/rust-lang/rust/issues/43036
-
-------------------------
-
-This feature enables the `repr(transparent)` attribute on structs, which enables
-the use of newtypes without the usual ABI implications of wrapping the value in
-a struct.
-
-## Background
-
-It's sometimes useful to add additional type safety by introducing *newtypes*.
-For example, code that handles numeric quantities in different units such as
-millimeters, centimeters, grams, kilograms, etc. may want to use the type system
-to rule out mistakes such as adding millimeters to grams:
-
-```rust
-use std::ops::Add;
-
-struct Millimeters(f64);
-struct Grams(f64);
-
-impl Add<Millimeters> for Millimeters {
-    type Output = Millimeters;
-
-    fn add(self, other: Millimeters) -> Millimeters {
-        Millimeters(self.0 + other.0)
-    }
-}
-
-// Likewise: impl Add<Grams> for Grams {}
-```
-
-Other uses of newtypes include using `PhantomData` to add lifetimes to raw
-pointers or to implement the "phantom types" pattern. See the [PhantomData]
-documentation and [the Nomicon][nomicon-phantom] for more details.
-
-The added type safety is especially useful when interacting with C or other
-languages. However, in those cases we need to ensure the newtypes we add do not
-introduce incompatibilities with the C ABI.
-
-## Newtypes in FFI
-
-Luckily, `repr(C)` newtypes are laid out just like the type they wrap on all
-platforms which Rust currently supports, and likely on many more. For example,
-consider this C declaration:
-
-```C
-struct Object {
-    double weight; //< in grams
-    double height; //< in millimeters
-    // ...
-}
-
-void frobnicate(struct Object *);
-```
-
-While using this C code from Rust, we could add `repr(C)` to the `Grams` and
-`Millimeters` newtypes introduced above and use them to add some type safety
-while staying compatible with the memory layout of `Object`:
-
-```rust,no_run
-#[repr(C)]
-struct Grams(f64);
-
-#[repr(C)]
-struct Millimeters(f64);
-
-#[repr(C)]
-struct Object {
-    weight: Grams,
-    height: Millimeters,
-    // ...
-}
-
-extern {
-    fn frobnicate(_: *mut Object);
-}
-```
-
-This works even when adding some `PhantomData` fields, because they are
-zero-sized and therefore don't have to affect the memory layout.
-
-However, there's more to the ABI than just memory layout: there's also the
-question of how function call arguments and return values are passed. Many
-common ABI treat a struct containing a single field differently from that field
-itself, at least when the field is a scalar (e.g., integer or float or pointer).
-
-To continue the above example, suppose the C library also exposes a function
-like this:
-
-```C
-double calculate_weight(double height);
-```
-
-Using our newtypes on the Rust side like this will cause an ABI mismatch on many
-platforms:
-
-```rust,ignore
-extern {
-    fn calculate_weight(height: Millimeters) -> Grams;
-}
-```
-
-For example, on x86_64 Linux, Rust will pass the argument in an integer
-register, while the C function expects the argument to be in a floating-point
-register. Likewise, the C function will return the result in a floating-point
-register while Rust will expect it in an integer register.
-
-Note that this problem is not specific to floats: To give another example,
-32-bit x86 linux will pass and return `struct Foo(i32);` on the stack while
-`i32` is placed in registers.
-
-## Enter `repr(transparent)`
-
-So while `repr(C)` happens to do the right thing with respect to memory layout,
-it's not quite the right tool for newtypes in FFI. Instead of declaring a C
-struct, we need to communicate to the Rust compiler that our newtype is just for
-type safety on the Rust side. This is what `repr(transparent)` does.
-
-The attribute can be applied to a newtype-like structs that contains a single
-field. It indicates that the newtype should be represented exactly like that
-field's type, i.e., the newtype should be ignored for ABI purpopses: not only is
-it laid out the same in memory, it is also passed identically in function calls.
-
-In the above example, the ABI mismatches can be prevented by making the newtypes
-`Grams` and `Millimeters` transparent like this:
-
-```rust
-#![feature(repr_transparent)]
-
-#[repr(transparent)]
-struct Grams(f64);
-
-#[repr(transparent)]
-struct Millimeters(f64);
-```
-
-In addition to that single field, any number of zero-sized fields are permitted,
-including but not limited to `PhantomData`:
-
-```rust
-#![feature(repr_transparent)]
-
-use std::marker::PhantomData;
-
-struct Foo { /* ... */ }
-
-#[repr(transparent)]
-struct FooPtrWithLifetime<'a>(*const Foo, PhantomData<&'a Foo>);
-
-#[repr(transparent)]
-struct NumberWithUnit<T, U>(T, PhantomData<U>);
-
-struct CustomZst;
-
-#[repr(transparent)]
-struct PtrWithCustomZst<'a> {
-    ptr: FooPtrWithLifetime<'a>,
-    some_marker: CustomZst,
-}
-```
-
-Transparent structs can be nested: `PtrWithCustomZst` is also represented
-exactly like `*const Foo`.
-
-Because `repr(transparent)` delegates all representation concerns to another
-type, it is incompatible with all other `repr(..)` attributes. It also cannot be
-applied to enums, unions, empty structs, structs whose fields are all
-zero-sized, or structs with *multiple* non-zero-sized fields.
-
-[PhantomData]: https://doc.rust-lang.org/std/marker/struct.PhantomData.html
-[nomicon-phantom]: https://doc.rust-lang.org/nomicon/phantom-data.html
diff --git a/src/doc/unstable-book/src/language-features/used.md b/src/doc/unstable-book/src/language-features/used.md
index 75a8b27..c3b7f2e 100644
--- a/src/doc/unstable-book/src/language-features/used.md
+++ b/src/doc/unstable-book/src/language-features/used.md
@@ -87,11 +87,13 @@
 script.
 
 ``` rust,ignore
-#![feature(lang_items)]
+#![feature(panic_implementation)]
 #![feature(used)]
 #![no_main]
 #![no_std]
 
+use core::panic::PanicInfo;
+
 extern "C" fn reset_handler() -> ! {
     loop {}
 }
@@ -100,8 +102,10 @@
 #[used]
 static RESET_HANDLER: extern "C" fn() -> ! = reset_handler;
 
-#[lang = "panic_fmt"]
-fn panic_fmt() {}
+#[panic_implementation]
+fn panic_impl(info: &PanicInfo) -> ! {
+    loop {}
+}
 ```
 
 ``` text
diff --git a/src/doc/unstable-book/src/library-features/alloc-jemalloc.md b/src/doc/unstable-book/src/library-features/alloc-jemalloc.md
deleted file mode 100644
index 425d4cb..0000000
--- a/src/doc/unstable-book/src/library-features/alloc-jemalloc.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# `alloc_jemalloc`
-
-The tracking issue for this feature is: [#33082]
-
-[#33082]: https://github.com/rust-lang/rust/issues/33082
-
-See also [`alloc_system`](library-features/alloc-system.html).
-
-------------------------
-
-This feature has been replaced by [the `jemallocator` crate on crates.io.][jemallocator].
-
-[jemallocator]: https://crates.io/crates/jemallocator
diff --git a/src/doc/unstable-book/src/library-features/alloc-system.md b/src/doc/unstable-book/src/library-features/alloc-system.md
deleted file mode 100644
index 9effab2..0000000
--- a/src/doc/unstable-book/src/library-features/alloc-system.md
+++ /dev/null
@@ -1,77 +0,0 @@
-# `alloc_system`
-
-The tracking issue for this feature is: [#32838]
-
-[#32838]: https://github.com/rust-lang/rust/issues/32838
-
-See also [`global_allocator`](language-features/global-allocator.html).
-
-------------------------
-
-The compiler currently ships two default allocators: `alloc_system` and
-`alloc_jemalloc` (some targets don't have jemalloc, however). These allocators
-are normal Rust crates and contain an implementation of the routines to
-allocate and deallocate memory. The standard library is not compiled assuming
-either one, and the compiler will decide which allocator is in use at
-compile-time depending on the type of output artifact being produced.
-
-Binaries generated by the compiler will use `alloc_jemalloc` by default (where
-available). In this situation the compiler "controls the world" in the sense of
-it has power over the final link. Primarily this means that the allocator
-decision can be left up the compiler.
-
-Dynamic and static libraries, however, will use `alloc_system` by default. Here
-Rust is typically a 'guest' in another application or another world where it
-cannot authoritatively decide what allocator is in use. As a result it resorts
-back to the standard APIs (e.g. `malloc` and `free`) for acquiring and releasing
-memory.
-
-# Switching Allocators
-
-Although the compiler's default choices may work most of the time, it's often
-necessary to tweak certain aspects. Overriding the compiler's decision about
-which allocator is in use is done through the `#[global_allocator]` attribute:
-
-```rust,no_run
-#![feature(alloc_system, global_allocator, allocator_api)]
-
-extern crate alloc_system;
-
-use alloc_system::System;
-
-#[global_allocator]
-static A: System = System;
-
-fn main() {
-    let a = Box::new(4); // Allocates from the system allocator.
-    println!("{}", a);
-}
-```
-
-In this example the binary generated will not link to jemalloc by default but
-instead use the system allocator. Conversely to generate a dynamic library which
-uses jemalloc by default one would write:
-
-(The `alloc_jemalloc` crate cannot be used to control the global allocator,
-crate.io’s `jemallocator` crate provides equivalent functionality.)
-
-```toml
-# Cargo.toml
-[dependencies]
-jemallocator = "0.1"
-```
-```rust,ignore
-#![feature(global_allocator)]
-#![crate_type = "dylib"]
-
-extern crate jemallocator;
-
-#[global_allocator]
-static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
-
-pub fn foo() {
-    let a = Box::new(4); // Allocates from jemalloc.
-    println!("{}", a);
-}
-# fn main() {}
-```
diff --git a/src/doc/unstable-book/src/library-features/entry-or-default.md b/src/doc/unstable-book/src/library-features/entry-or-default.md
deleted file mode 100644
index f8c8a2a..0000000
--- a/src/doc/unstable-book/src/library-features/entry-or-default.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# `entry_or_default`
-
-The tracking issue for this feature is: [#44324]
-
-[#44324]: https://github.com/rust-lang/rust/issues/44324
-
-------------------------
-
-The `entry_or_default` feature adds a new method to `hash_map::Entry`
-and `btree_map::Entry`, `or_default`, when `V: Default`. This method is
-semantically identical to `or_insert_with(Default::default)`, and will
-insert the default value for the type if no entry exists for the current
-key.
diff --git a/src/etc/htmldocck.py b/src/etc/htmldocck.py
index 8a11c6f..569788f 100644
--- a/src/etc/htmldocck.py
+++ b/src/etc/htmldocck.py
@@ -346,15 +346,19 @@
 def check_tree_text(tree, path, pat, regexp):
     path = normalize_xpath(path)
     ret = False
-    for e in tree.findall(path):
-        try:
-            value = flatten(e)
-        except KeyError:
-            continue
-        else:
-            ret = check_string(value, pat, regexp)
-            if ret:
-                break
+    try:
+        for e in tree.findall(path):
+            try:
+                value = flatten(e)
+            except KeyError:
+                continue
+            else:
+                ret = check_string(value, pat, regexp)
+                if ret:
+                    break
+    except Exception as e:
+        print('Failed to get path "{}"'.format(path))
+        raise e
     return ret
 
 
diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs
index 8753c49..04c8063 100644
--- a/src/liballoc/alloc.rs
+++ b/src/liballoc/alloc.rs
@@ -8,17 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![unstable(feature = "allocator_api",
-            reason = "the precise API and guarantees it provides may be tweaked \
-                      slightly, especially to possibly take into account the \
-                      types being stored to make room for a future \
-                      tracing garbage collector",
-            issue = "32838")]
+//! Memory allocation APIs
+
+#![stable(feature = "alloc_module", since = "1.28.0")]
 
 use core::intrinsics::{min_align_of_val, size_of_val};
 use core::ptr::{NonNull, Unique};
 use core::usize;
 
+#[stable(feature = "alloc_module", since = "1.28.0")]
 #[doc(inline)]
 pub use core::alloc::*;
 
@@ -37,67 +35,112 @@
     fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8;
 }
 
+/// The global memory allocator.
+///
+/// This type implements the [`Alloc`] trait by forwarding calls
+/// to the allocator registered with the `#[global_allocator]` attribute
+/// if there is one, or the `std` crate’s default.
+#[unstable(feature = "allocator_api", issue = "32838")]
 #[derive(Copy, Clone, Default, Debug)]
 pub struct Global;
 
-#[unstable(feature = "allocator_api", issue = "32838")]
-#[rustc_deprecated(since = "1.27.0", reason = "type renamed to `Global`")]
-pub type Heap = Global;
-
-#[unstable(feature = "allocator_api", issue = "32838")]
-#[rustc_deprecated(since = "1.27.0", reason = "type renamed to `Global`")]
-#[allow(non_upper_case_globals)]
-pub const Heap: Global = Global;
-
-unsafe impl GlobalAlloc for Global {
-    #[inline]
-    unsafe fn alloc(&self, layout: Layout) -> *mut Opaque {
-        let ptr = __rust_alloc(layout.size(), layout.align());
-        ptr as *mut Opaque
-    }
-
-    #[inline]
-    unsafe fn dealloc(&self, ptr: *mut Opaque, layout: Layout) {
-        __rust_dealloc(ptr as *mut u8, layout.size(), layout.align())
-    }
-
-    #[inline]
-    unsafe fn realloc(&self, ptr: *mut Opaque, layout: Layout, new_size: usize) -> *mut Opaque {
-        let ptr = __rust_realloc(ptr as *mut u8, layout.size(), layout.align(), new_size);
-        ptr as *mut Opaque
-    }
-
-    #[inline]
-    unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut Opaque {
-        let ptr = __rust_alloc_zeroed(layout.size(), layout.align());
-        ptr as *mut Opaque
-    }
+/// Allocate memory with the global allocator.
+///
+/// This function forwards calls to the [`GlobalAlloc::alloc`] method
+/// of the allocator registered with the `#[global_allocator]` attribute
+/// if there is one, or the `std` crate’s default.
+///
+/// This function is expected to be deprecated in favor of the `alloc` method
+/// of the [`Global`] type when it and the [`Alloc`] trait become stable.
+///
+/// # Safety
+///
+/// See [`GlobalAlloc::alloc`].
+#[stable(feature = "global_alloc", since = "1.28.0")]
+#[inline]
+pub unsafe fn alloc(layout: Layout) -> *mut u8 {
+    __rust_alloc(layout.size(), layout.align())
 }
 
+/// Deallocate memory with the global allocator.
+///
+/// This function forwards calls to the [`GlobalAlloc::dealloc`] method
+/// of the allocator registered with the `#[global_allocator]` attribute
+/// if there is one, or the `std` crate’s default.
+///
+/// This function is expected to be deprecated in favor of the `dealloc` method
+/// of the [`Global`] type when it and the [`Alloc`] trait become stable.
+///
+/// # Safety
+///
+/// See [`GlobalAlloc::dealloc`].
+#[stable(feature = "global_alloc", since = "1.28.0")]
+#[inline]
+pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) {
+    __rust_dealloc(ptr, layout.size(), layout.align())
+}
+
+/// Reallocate memory with the global allocator.
+///
+/// This function forwards calls to the [`GlobalAlloc::realloc`] method
+/// of the allocator registered with the `#[global_allocator]` attribute
+/// if there is one, or the `std` crate’s default.
+///
+/// This function is expected to be deprecated in favor of the `realloc` method
+/// of the [`Global`] type when it and the [`Alloc`] trait become stable.
+///
+/// # Safety
+///
+/// See [`GlobalAlloc::realloc`].
+#[stable(feature = "global_alloc", since = "1.28.0")]
+#[inline]
+pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
+    __rust_realloc(ptr, layout.size(), layout.align(), new_size)
+}
+
+/// Allocate zero-initialized memory with the global allocator.
+///
+/// This function forwards calls to the [`GlobalAlloc::alloc_zeroed`] method
+/// of the allocator registered with the `#[global_allocator]` attribute
+/// if there is one, or the `std` crate’s default.
+///
+/// This function is expected to be deprecated in favor of the `alloc_zeroed` method
+/// of the [`Global`] type when it and the [`Alloc`] trait become stable.
+///
+/// # Safety
+///
+/// See [`GlobalAlloc::alloc_zeroed`].
+#[stable(feature = "global_alloc", since = "1.28.0")]
+#[inline]
+pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 {
+    __rust_alloc_zeroed(layout.size(), layout.align())
+}
+
+#[unstable(feature = "allocator_api", issue = "32838")]
 unsafe impl Alloc for Global {
     #[inline]
-    unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<Opaque>, AllocErr> {
-        NonNull::new(GlobalAlloc::alloc(self, layout)).ok_or(AllocErr)
+    unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
+        NonNull::new(alloc(layout)).ok_or(AllocErr)
     }
 
     #[inline]
-    unsafe fn dealloc(&mut self, ptr: NonNull<Opaque>, layout: Layout) {
-        GlobalAlloc::dealloc(self, ptr.as_ptr(), layout)
+    unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
+        dealloc(ptr.as_ptr(), layout)
     }
 
     #[inline]
     unsafe fn realloc(&mut self,
-                      ptr: NonNull<Opaque>,
+                      ptr: NonNull<u8>,
                       layout: Layout,
                       new_size: usize)
-                      -> Result<NonNull<Opaque>, AllocErr>
+                      -> Result<NonNull<u8>, AllocErr>
     {
-        NonNull::new(GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size)).ok_or(AllocErr)
+        NonNull::new(realloc(ptr.as_ptr(), layout, new_size)).ok_or(AllocErr)
     }
 
     #[inline]
-    unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<Opaque>, AllocErr> {
-        NonNull::new(GlobalAlloc::alloc_zeroed(self, layout)).ok_or(AllocErr)
+    unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
+        NonNull::new(alloc_zeroed(layout)).ok_or(AllocErr)
     }
 }
 
@@ -111,9 +154,9 @@
         align as *mut u8
     } else {
         let layout = Layout::from_size_align_unchecked(size, align);
-        let ptr = Global.alloc(layout);
+        let ptr = alloc(layout);
         if !ptr.is_null() {
-            ptr as *mut u8
+            ptr
         } else {
             oom(layout)
         }
@@ -129,10 +172,23 @@
     // We do not allocate for Box<T> when T is ZST, so deallocation is also not necessary.
     if size != 0 {
         let layout = Layout::from_size_align_unchecked(size, align);
-        Global.dealloc(ptr as *mut Opaque, layout);
+        dealloc(ptr as *mut u8, layout);
     }
 }
 
+/// Abort on memory allocation error or failure.
+///
+/// Callers of memory allocation APIs wishing to abort computation
+/// in response to an allocation error are encouraged to call this function,
+/// rather than directly invoking `panic!` or similar.
+///
+/// The default behavior of this function is to print a message to standard error
+/// and abort the process.
+/// It can be replaced with [`set_oom_hook`] and [`take_oom_hook`].
+///
+/// [`set_oom_hook`]: ../../std/alloc/fn.set_oom_hook.html
+/// [`take_oom_hook`]: ../../std/alloc/fn.take_oom_hook.html
+#[stable(feature = "global_alloc", since = "1.28.0")]
 #[rustc_allocator_nounwind]
 pub fn oom(layout: Layout) -> ! {
     #[allow(improper_ctypes)]
diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs
index 4026b3a..e3369f0 100644
--- a/src/liballoc/arc.rs
+++ b/src/liballoc/arc.rs
@@ -519,7 +519,7 @@
 
         if self.inner().weak.fetch_sub(1, Release) == 1 {
             atomic::fence(Acquire);
-            Global.dealloc(self.ptr.as_opaque(), Layout::for_value(self.ptr.as_ref()))
+            Global.dealloc(self.ptr.cast(), Layout::for_value(self.ptr.as_ref()))
         }
     }
 
@@ -639,7 +639,7 @@
                     let slice = from_raw_parts_mut(self.elems, self.n_elems);
                     ptr::drop_in_place(slice);
 
-                    Global.dealloc(self.mem.as_opaque(), self.layout.clone());
+                    Global.dealloc(self.mem.cast(), self.layout.clone());
                 }
             }
         }
@@ -1196,7 +1196,7 @@
         if self.inner().weak.fetch_sub(1, Release) == 1 {
             atomic::fence(Acquire);
             unsafe {
-                Global.dealloc(self.ptr.as_opaque(), Layout::for_value(self.ptr.as_ref()))
+                Global.dealloc(self.ptr.cast(), Layout::for_value(self.ptr.as_ref()))
             }
         }
     }
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index a83ce7f..ea60c77 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -59,12 +59,14 @@
 use core::borrow;
 use core::cmp::Ordering;
 use core::fmt;
+use core::future::Future;
 use core::hash::{Hash, Hasher};
 use core::iter::FusedIterator;
 use core::marker::{Unpin, Unsize};
 use core::mem::{self, PinMut};
 use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState};
 use core::ptr::{self, NonNull, Unique};
+use core::task::{Context, Poll, UnsafeTask, TaskObj};
 use core::convert::From;
 
 use raw_vec::RawVec;
@@ -755,6 +757,7 @@
 /// A pinned, heap allocated reference.
 #[unstable(feature = "pin", issue = "49150")]
 #[fundamental]
+#[repr(transparent)]
 pub struct PinBox<T: ?Sized> {
     inner: Box<T>,
 }
@@ -771,14 +774,72 @@
 #[unstable(feature = "pin", issue = "49150")]
 impl<T: ?Sized> PinBox<T> {
     /// Get a pinned reference to the data in this PinBox.
+    #[inline]
     pub fn as_pin_mut<'a>(&'a mut self) -> PinMut<'a, T> {
         unsafe { PinMut::new_unchecked(&mut *self.inner) }
     }
 
+    /// Constructs a `PinBox` from a raw pointer.
+    ///
+    /// After calling this function, the raw pointer is owned by the
+    /// resulting `PinBox`. Specifically, the `PinBox` destructor will call
+    /// the destructor of `T` and free the allocated memory. Since the
+    /// way `PinBox` allocates and releases memory is unspecified, the
+    /// only valid pointer to pass to this function is the one taken
+    /// from another `PinBox` via the [`PinBox::into_raw`] function.
+    ///
+    /// This function is unsafe because improper use may lead to
+    /// memory problems. For example, a double-free may occur if the
+    /// function is called twice on the same raw pointer.
+    ///
+    /// [`PinBox::into_raw`]: struct.PinBox.html#method.into_raw
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(pin)]
+    /// use std::boxed::PinBox;
+    /// let x = PinBox::new(5);
+    /// let ptr = PinBox::into_raw(x);
+    /// let x = unsafe { PinBox::from_raw(ptr) };
+    /// ```
+    #[inline]
+    pub unsafe fn from_raw(raw: *mut T) -> Self {
+        PinBox { inner: Box::from_raw(raw) }
+    }
+
+    /// Consumes the `PinBox`, returning the wrapped raw pointer.
+    ///
+    /// After calling this function, the caller is responsible for the
+    /// memory previously managed by the `PinBox`. In particular, the
+    /// caller should properly destroy `T` and release the memory. The
+    /// proper way to do so is to convert the raw pointer back into a
+    /// `PinBox` with the [`PinBox::from_raw`] function.
+    ///
+    /// Note: this is an associated function, which means that you have
+    /// to call it as `PinBox::into_raw(b)` instead of `b.into_raw()`. This
+    /// is so that there is no conflict with a method on the inner type.
+    ///
+    /// [`PinBox::from_raw`]: struct.PinBox.html#method.from_raw
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(pin)]
+    /// use std::boxed::PinBox;
+    /// let x = PinBox::new(5);
+    /// let ptr = PinBox::into_raw(x);
+    /// ```
+    #[inline]
+    pub fn into_raw(b: PinBox<T>) -> *mut T {
+        Box::into_raw(b.inner)
+    }
+
     /// Get a mutable reference to the data inside this PinBox.
     ///
     /// This function is unsafe. Users must guarantee that the data is never
     /// moved out of this reference.
+    #[inline]
     pub unsafe fn get_mut<'a>(this: &'a mut PinBox<T>) -> &'a mut T {
         &mut *this.inner
     }
@@ -787,6 +848,7 @@
     ///
     /// This function is unsafe. Users must guarantee that the data is never
     /// moved out of the box.
+    #[inline]
     pub unsafe fn unpin(this: PinBox<T>) -> Box<T> {
         this.inner
     }
@@ -851,3 +913,52 @@
 
 #[unstable(feature = "pin", issue = "49150")]
 impl<T: ?Sized> Unpin for PinBox<T> {}
+
+#[unstable(feature = "futures_api", issue = "50547")]
+impl<'a, F: ?Sized + Future + Unpin> Future for Box<F> {
+    type Output = F::Output;
+
+    fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
+        PinMut::new(&mut **self).poll(cx)
+    }
+}
+
+#[unstable(feature = "futures_api", issue = "50547")]
+impl<'a, F: ?Sized + Future> Future for PinBox<F> {
+    type Output = F::Output;
+
+    fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
+        self.as_pin_mut().poll(cx)
+    }
+}
+
+#[unstable(feature = "futures_api", issue = "50547")]
+unsafe impl<F: Future<Output = ()> + Send + 'static> UnsafeTask for PinBox<F> {
+    fn into_raw(self) -> *mut () {
+        PinBox::into_raw(self) as *mut ()
+    }
+
+    unsafe fn poll(task: *mut (), cx: &mut Context) -> Poll<()> {
+        let ptr = task as *mut F;
+        let pin: PinMut<F> = PinMut::new_unchecked(&mut *ptr);
+        pin.poll(cx)
+    }
+
+    unsafe fn drop(task: *mut ()) {
+        drop(PinBox::from_raw(task as *mut F))
+    }
+}
+
+#[unstable(feature = "futures_api", issue = "50547")]
+impl<F: Future<Output = ()> + Send + 'static> From<PinBox<F>> for TaskObj {
+    fn from(boxed: PinBox<F>) -> Self {
+        TaskObj::new(boxed)
+    }
+}
+
+#[unstable(feature = "futures_api", issue = "50547")]
+impl<F: Future<Output = ()> + Send + 'static> From<Box<F>> for TaskObj {
+    fn from(boxed: Box<F>) -> Self {
+        TaskObj::new(PinBox::from(boxed))
+    }
+}
diff --git a/src/liballoc/btree/map.rs b/src/liballoc/btree/map.rs
index 28c4214..e6e4544 100644
--- a/src/liballoc/btree/map.rs
+++ b/src/liballoc/btree/map.rs
@@ -2184,14 +2184,13 @@
 }
 
 impl<'a, K: Ord, V: Default> Entry<'a, K, V> {
-    #[unstable(feature = "entry_or_default", issue = "44324")]
+    #[stable(feature = "entry_or_default", since = "1.28.0")]
     /// Ensures a value is in the entry by inserting the default value if empty,
     /// and returns a mutable reference to the value in the entry.
     ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(entry_or_default)]
     /// # fn main() {
     /// use std::collections::BTreeMap;
     ///
@@ -2369,6 +2368,11 @@
 
     /// Gets a mutable reference to the value in the entry.
     ///
+    /// If you need a reference to the `OccupiedEntry` which may outlive the
+    /// destruction of the `Entry` value, see [`into_mut`].
+    ///
+    /// [`into_mut`]: #method.into_mut
+    ///
     /// # Examples
     ///
     /// ```
@@ -2380,9 +2384,13 @@
     ///
     /// assert_eq!(map["poneyland"], 12);
     /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
-    ///      *o.get_mut() += 10;
+    ///     *o.get_mut() += 10;
+    ///     assert_eq!(*o.get(), 22);
+    ///
+    ///     // We can use the same Entry multiple times.
+    ///     *o.get_mut() += 2;
     /// }
-    /// assert_eq!(map["poneyland"], 22);
+    /// assert_eq!(map["poneyland"], 24);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut(&mut self) -> &mut V {
@@ -2391,6 +2399,10 @@
 
     /// Converts the entry into a mutable reference to its value.
     ///
+    /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`].
+    ///
+    /// [`get_mut`]: #method.get_mut
+    ///
     /// # Examples
     ///
     /// ```
diff --git a/src/liballoc/btree/node.rs b/src/liballoc/btree/node.rs
index 431695c..19bdcbc 100644
--- a/src/liballoc/btree/node.rs
+++ b/src/liballoc/btree/node.rs
@@ -287,7 +287,7 @@
         self.as_mut().as_leaf_mut().parent = ptr::null();
 
         unsafe {
-            Global.dealloc(NonNull::from(top).as_opaque(), Layout::new::<InternalNode<K, V>>());
+            Global.dealloc(NonNull::from(top).cast(), Layout::new::<InternalNode<K, V>>());
         }
     }
 }
@@ -478,7 +478,7 @@
         debug_assert!(!self.is_shared_root());
         let node = self.node;
         let ret = self.ascend().ok();
-        Global.dealloc(node.as_opaque(), Layout::new::<LeafNode<K, V>>());
+        Global.dealloc(node.cast(), Layout::new::<LeafNode<K, V>>());
         ret
     }
 }
@@ -499,7 +499,7 @@
     > {
         let node = self.node;
         let ret = self.ascend().ok();
-        Global.dealloc(node.as_opaque(), Layout::new::<InternalNode<K, V>>());
+        Global.dealloc(node.cast(), Layout::new::<InternalNode<K, V>>());
         ret
     }
 }
@@ -1321,12 +1321,12 @@
                 }
 
                 Global.dealloc(
-                    right_node.node.as_opaque(),
+                    right_node.node.cast(),
                     Layout::new::<InternalNode<K, V>>(),
                 );
             } else {
                 Global.dealloc(
-                    right_node.node.as_opaque(),
+                    right_node.node.cast(),
                     Layout::new::<LeafNode<K, V>>(),
                 );
             }
diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs
index a4e5373..b49ec0a 100644
--- a/src/liballoc/fmt.rs
+++ b/src/liballoc/fmt.rs
@@ -531,6 +531,8 @@
 pub use core::fmt::{write, ArgumentV1, Arguments};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::fmt::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple};
+#[stable(feature = "fmt_flags_align", since = "1.28.0")]
+pub use core::fmt::{Alignment};
 
 use string;
 
diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs
deleted file mode 100644
index 16f0630..0000000
--- a/src/liballoc/heap.rs
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2014-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.
-
-#![allow(deprecated)]
-
-pub use alloc::{Layout, AllocErr, CannotReallocInPlace, Opaque};
-use core::alloc::Alloc as CoreAlloc;
-use core::ptr::NonNull;
-
-#[doc(hidden)]
-pub mod __core {
-    pub use core::*;
-}
-
-#[derive(Debug)]
-pub struct Excess(pub *mut u8, pub usize);
-
-/// Compatibility with older versions of #[global_allocator] during bootstrap
-pub unsafe trait Alloc {
-    unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr>;
-    unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout);
-    fn oom(&mut self, err: AllocErr) -> !;
-    fn usable_size(&self, layout: &Layout) -> (usize, usize);
-    unsafe fn realloc(&mut self,
-                      ptr: *mut u8,
-                      layout: Layout,
-                      new_layout: Layout) -> Result<*mut u8, AllocErr>;
-    unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr>;
-    unsafe fn alloc_excess(&mut self, layout: Layout) -> Result<Excess, AllocErr>;
-    unsafe fn realloc_excess(&mut self,
-                             ptr: *mut u8,
-                             layout: Layout,
-                             new_layout: Layout) -> Result<Excess, AllocErr>;
-    unsafe fn grow_in_place(&mut self,
-                            ptr: *mut u8,
-                            layout: Layout,
-                            new_layout: Layout) -> Result<(), CannotReallocInPlace>;
-    unsafe fn shrink_in_place(&mut self,
-                              ptr: *mut u8,
-                              layout: Layout,
-                              new_layout: Layout) -> Result<(), CannotReallocInPlace>;
-}
-
-unsafe impl<T> Alloc for T where T: CoreAlloc {
-    unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
-        CoreAlloc::alloc(self, layout).map(|ptr| ptr.cast().as_ptr())
-    }
-
-    unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) {
-        let ptr = NonNull::new_unchecked(ptr as *mut Opaque);
-        CoreAlloc::dealloc(self, ptr, layout)
-    }
-
-    fn oom(&mut self, _: AllocErr) -> ! {
-        unsafe { ::core::intrinsics::abort() }
-    }
-
-    fn usable_size(&self, layout: &Layout) -> (usize, usize) {
-        CoreAlloc::usable_size(self, layout)
-    }
-
-    unsafe fn realloc(&mut self,
-                      ptr: *mut u8,
-                      layout: Layout,
-                      new_layout: Layout) -> Result<*mut u8, AllocErr> {
-        let ptr = NonNull::new_unchecked(ptr as *mut Opaque);
-        CoreAlloc::realloc(self, ptr, layout, new_layout.size()).map(|ptr| ptr.cast().as_ptr())
-    }
-
-    unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
-        CoreAlloc::alloc_zeroed(self, layout).map(|ptr| ptr.cast().as_ptr())
-    }
-
-    unsafe fn alloc_excess(&mut self, layout: Layout) -> Result<Excess, AllocErr> {
-        CoreAlloc::alloc_excess(self, layout)
-            .map(|e| Excess(e.0 .cast().as_ptr(), e.1))
-    }
-
-    unsafe fn realloc_excess(&mut self,
-                             ptr: *mut u8,
-                             layout: Layout,
-                             new_layout: Layout) -> Result<Excess, AllocErr> {
-        let ptr = NonNull::new_unchecked(ptr as *mut Opaque);
-        CoreAlloc::realloc_excess(self, ptr, layout, new_layout.size())
-            .map(|e| Excess(e.0 .cast().as_ptr(), e.1))
-    }
-
-    unsafe fn grow_in_place(&mut self,
-                            ptr: *mut u8,
-                            layout: Layout,
-                            new_layout: Layout) -> Result<(), CannotReallocInPlace> {
-        let ptr = NonNull::new_unchecked(ptr as *mut Opaque);
-        CoreAlloc::grow_in_place(self, ptr, layout, new_layout.size())
-    }
-
-    unsafe fn shrink_in_place(&mut self,
-                              ptr: *mut u8,
-                              layout: Layout,
-                              new_layout: Layout) -> Result<(), CannotReallocInPlace> {
-        let ptr = NonNull::new_unchecked(ptr as *mut Opaque);
-        CoreAlloc::shrink_in_place(self, ptr, layout, new_layout.size())
-    }
-}
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 91de3ad..e25742a 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -80,6 +80,7 @@
 #![cfg_attr(test, feature(rand, test))]
 #![feature(allocator_api)]
 #![feature(allow_internal_unstable)]
+#![feature(arbitrary_self_types)]
 #![feature(ascii_ctype)]
 #![feature(box_into_raw_non_null)]
 #![feature(box_patterns)]
@@ -95,6 +96,7 @@
 #![feature(fmt_internals)]
 #![feature(from_ref)]
 #![feature(fundamental)]
+#![feature(futures_api)]
 #![feature(lang_items)]
 #![feature(libc)]
 #![feature(needs_allocator)]
@@ -103,8 +105,8 @@
 #![feature(pin)]
 #![feature(ptr_internals)]
 #![feature(ptr_offset_from)]
+#![cfg_attr(stage0, feature(repr_transparent))]
 #![feature(rustc_attrs)]
-#![feature(slice_get_slice)]
 #![feature(specialization)]
 #![feature(staged_api)]
 #![feature(str_internals)]
@@ -149,14 +151,10 @@
 
 pub mod alloc;
 
-#[unstable(feature = "allocator_api", issue = "32838")]
-#[rustc_deprecated(since = "1.27.0", reason = "module renamed to `alloc`")]
-/// Use the `alloc` module instead.
-pub mod heap {
-    pub use alloc::*;
-}
-
-
+#[unstable(feature = "futures_api",
+           reason = "futures in libcore are unstable",
+           issue = "50547")]
+pub mod task;
 // Primitive types using the heaps above
 
 // Need to conditionally define the mod from `boxed.rs` to avoid
diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs
index 07bb7f1..d1f140e 100644
--- a/src/liballoc/raw_vec.rs
+++ b/src/liballoc/raw_vec.rs
@@ -93,7 +93,7 @@
 
             // handles ZSTs and `cap = 0` alike
             let ptr = if alloc_size == 0 {
-                NonNull::<T>::dangling().as_opaque()
+                NonNull::<T>::dangling()
             } else {
                 let align = mem::align_of::<T>();
                 let layout = Layout::from_size_align(alloc_size, align).unwrap();
@@ -103,13 +103,13 @@
                     a.alloc(layout)
                 };
                 match result {
-                    Ok(ptr) => ptr,
+                    Ok(ptr) => ptr.cast(),
                     Err(_) => oom(layout),
                 }
             };
 
             RawVec {
-                ptr: ptr.cast().into(),
+                ptr: ptr.into(),
                 cap,
                 a,
             }
@@ -314,7 +314,7 @@
                     let new_cap = 2 * self.cap;
                     let new_size = new_cap * elem_size;
                     alloc_guard(new_size).unwrap_or_else(|_| capacity_overflow());
-                    let ptr_res = self.a.realloc(NonNull::from(self.ptr).as_opaque(),
+                    let ptr_res = self.a.realloc(NonNull::from(self.ptr).cast(),
                                                  cur,
                                                  new_size);
                     match ptr_res {
@@ -373,7 +373,7 @@
             let new_cap = 2 * self.cap;
             let new_size = new_cap * elem_size;
             alloc_guard(new_size).unwrap_or_else(|_| capacity_overflow());
-            match self.a.grow_in_place(NonNull::from(self.ptr).as_opaque(), old_layout, new_size) {
+            match self.a.grow_in_place(NonNull::from(self.ptr).cast(), old_layout, new_size) {
                 Ok(_) => {
                     // We can't directly divide `size`.
                     self.cap = new_cap;
@@ -546,7 +546,7 @@
             // FIXME: may crash and burn on over-reserve
             alloc_guard(new_layout.size()).unwrap_or_else(|_| capacity_overflow());
             match self.a.grow_in_place(
-                NonNull::from(self.ptr).as_opaque(), old_layout, new_layout.size(),
+                NonNull::from(self.ptr).cast(), old_layout, new_layout.size(),
             ) {
                 Ok(_) => {
                     self.cap = new_cap;
@@ -607,7 +607,7 @@
                 let new_size = elem_size * amount;
                 let align = mem::align_of::<T>();
                 let old_layout = Layout::from_size_align_unchecked(old_size, align);
-                match self.a.realloc(NonNull::from(self.ptr).as_opaque(),
+                match self.a.realloc(NonNull::from(self.ptr).cast(),
                                      old_layout,
                                      new_size) {
                     Ok(p) => self.ptr = p.cast().into(),
@@ -667,7 +667,7 @@
             let res = match self.current_layout() {
                 Some(layout) => {
                     debug_assert!(new_layout.align() == layout.align());
-                    self.a.realloc(NonNull::from(self.ptr).as_opaque(), layout, new_layout.size())
+                    self.a.realloc(NonNull::from(self.ptr).cast(), layout, new_layout.size())
                 }
                 None => self.a.alloc(new_layout),
             };
@@ -710,7 +710,7 @@
         let elem_size = mem::size_of::<T>();
         if elem_size != 0 {
             if let Some(layout) = self.current_layout() {
-                self.a.dealloc(NonNull::from(self.ptr).as_opaque(), layout);
+                self.a.dealloc(NonNull::from(self.ptr).cast(), layout);
             }
         }
     }
@@ -753,7 +753,6 @@
 #[cfg(test)]
 mod tests {
     use super::*;
-    use alloc::Opaque;
 
     #[test]
     fn allocator_param() {
@@ -773,7 +772,7 @@
         // before allocation attempts start failing.
         struct BoundedAlloc { fuel: usize }
         unsafe impl Alloc for BoundedAlloc {
-            unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<Opaque>, AllocErr> {
+            unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
                 let size = layout.size();
                 if size > self.fuel {
                     return Err(AllocErr);
@@ -783,7 +782,7 @@
                     err @ Err(_) => err,
                 }
             }
-            unsafe fn dealloc(&mut self, ptr: NonNull<Opaque>, layout: Layout) {
+            unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
                 Global.dealloc(ptr, layout)
             }
         }
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 553c8b5..84a6ecf 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -259,7 +259,7 @@
 use core::ptr::{self, NonNull};
 use core::convert::From;
 
-use alloc::{Global, Alloc, Layout, Opaque, box_free, oom};
+use alloc::{Global, Alloc, Layout, box_free, oom};
 use string::String;
 use vec::Vec;
 
@@ -732,7 +732,7 @@
         // In the event of a panic, elements that have been written
         // into the new RcBox will be dropped, then the memory freed.
         struct Guard<T> {
-            mem: NonNull<Opaque>,
+            mem: NonNull<u8>,
             elems: *mut T,
             layout: Layout,
             n_elems: usize,
@@ -755,7 +755,7 @@
             let v_ptr = v as *const [T];
             let ptr = Self::allocate_for_ptr(v_ptr);
 
-            let mem = ptr as *mut _ as *mut Opaque;
+            let mem = ptr as *mut _ as *mut u8;
             let layout = Layout::for_value(&*ptr);
 
             // Pointer to first element
@@ -839,7 +839,7 @@
                 self.dec_weak();
 
                 if self.weak() == 0 {
-                    Global.dealloc(self.ptr.as_opaque(), Layout::for_value(self.ptr.as_ref()));
+                    Global.dealloc(self.ptr.cast(), Layout::for_value(self.ptr.as_ref()));
                 }
             }
         }
@@ -1263,7 +1263,7 @@
             // the weak count starts at 1, and will only go to zero if all
             // the strong pointers have disappeared.
             if self.weak() == 0 {
-                Global.dealloc(self.ptr.as_opaque(), Layout::for_value(self.ptr.as_ref()));
+                Global.dealloc(self.ptr.cast(), Layout::for_value(self.ptr.as_ref()));
             }
         }
     }
diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs
index 161493f..c27c596 100644
--- a/src/liballoc/slice.rs
+++ b/src/liballoc/slice.rs
@@ -121,7 +121,7 @@
 pub use core::slice::{from_raw_parts, from_raw_parts_mut};
 #[stable(feature = "from_ref", since = "1.28.0")]
 pub use core::slice::{from_ref, from_mut};
-#[unstable(feature = "slice_get_slice", issue = "35729")]
+#[stable(feature = "slice_get_slice", since = "1.28.0")]
 pub use core::slice::SliceIndex;
 #[unstable(feature = "exact_chunks", issue = "47115")]
 pub use core::slice::{ExactChunks, ExactChunksMut};
@@ -566,15 +566,17 @@
     }
 
     fn join(&self, sep: &T) -> Vec<T> {
+        let mut iter = self.iter();
+        let first = match iter.next() {
+            Some(first) => first,
+            None => return vec![],
+        };
         let size = self.iter().fold(0, |acc, v| acc + v.borrow().len());
         let mut result = Vec::with_capacity(size + self.len());
-        let mut first = true;
-        for v in self {
-            if first {
-                first = false
-            } else {
-                result.push(sep.clone())
-            }
+        result.extend_from_slice(first.borrow());
+
+        for v in iter {
+            result.push(sep.clone());
             result.extend_from_slice(v.borrow())
         }
         result
diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs
index 823e56b..32ca8d1 100644
--- a/src/liballoc/str.rs
+++ b/src/liballoc/str.rs
@@ -86,47 +86,13 @@
     type Output = String;
 
     fn concat(&self) -> String {
-        if self.is_empty() {
-            return String::new();
-        }
-
-        // `len` calculation may overflow but push_str will check boundaries
-        let len = self.iter().map(|s| s.borrow().len()).sum();
-        let mut result = String::with_capacity(len);
-
-        for s in self {
-            result.push_str(s.borrow())
-        }
-
-        result
+        self.join("")
     }
 
     fn join(&self, sep: &str) -> String {
-        if self.is_empty() {
-            return String::new();
+        unsafe {
+            String::from_utf8_unchecked( join_generic_copy(self, sep.as_bytes()) )
         }
-
-        // concat is faster
-        if sep.is_empty() {
-            return self.concat();
-        }
-
-        // this is wrong without the guarantee that `self` is non-empty
-        // `len` calculation may overflow but push_str but will check boundaries
-        let len = sep.len() * (self.len() - 1) +
-                  self.iter().map(|s| s.borrow().len()).sum::<usize>();
-        let mut result = String::with_capacity(len);
-        let mut first = true;
-
-        for s in self {
-            if first {
-                first = false;
-            } else {
-                result.push_str(sep);
-            }
-            result.push_str(s.borrow());
-        }
-        result
     }
 
     fn connect(&self, sep: &str) -> String {
@@ -134,6 +100,96 @@
     }
 }
 
+macro_rules! spezialize_for_lengths {
+    ($separator:expr, $target:expr, $iter:expr; $($num:expr),*) => {
+        let mut target = $target;
+        let iter = $iter;
+        let sep_bytes = $separator;
+        match $separator.len() {
+            $(
+                // loops with hardcoded sizes run much faster
+                // specialize the cases with small separator lengths
+                $num => {
+                    for s in iter {
+                        copy_slice_and_advance!(target, sep_bytes);
+                        copy_slice_and_advance!(target, s.borrow().as_ref());
+                    }
+                },
+            )*
+            _ => {
+                // arbitrary non-zero size fallback
+                for s in iter {
+                    copy_slice_and_advance!(target, sep_bytes);
+                    copy_slice_and_advance!(target, s.borrow().as_ref());
+                }
+            }
+        }
+    };
+}
+
+macro_rules! copy_slice_and_advance {
+    ($target:expr, $bytes:expr) => {
+        let len = $bytes.len();
+        let (head, tail) = {$target}.split_at_mut(len);
+        head.copy_from_slice($bytes);
+        $target = tail;
+    }
+}
+
+// Optimized join implementation that works for both Vec<T> (T: Copy) and String's inner vec
+// Currently (2018-05-13) there is a bug with type inference and specialization (see issue #36262)
+// For this reason SliceConcatExt<T> is not specialized for T: Copy and SliceConcatExt<str> is the
+// only user of this function. It is left in place for the time when that is fixed.
+//
+// the bounds for String-join are S: Borrow<str> and for Vec-join Borrow<[T]>
+// [T] and str both impl AsRef<[T]> for some T
+// => s.borrow().as_ref() and we always have slices
+fn join_generic_copy<B, T, S>(slice: &[S], sep: &[T]) -> Vec<T>
+where
+    T: Copy,
+    B: AsRef<[T]> + ?Sized,
+    S: Borrow<B>,
+{
+    let sep_len = sep.len();
+    let mut iter = slice.iter();
+
+    // the first slice is the only one without a separator preceding it
+    let first = match iter.next() {
+        Some(first) => first,
+        None => return vec![],
+    };
+
+    // compute the exact total length of the joined Vec
+    // if the `len` calculation overflows, we'll panic
+    // we would have run out of memory anyway and the rest of the function requires
+    // the entire Vec pre-allocated for safety
+    let len =  sep_len.checked_mul(iter.len()).and_then(|n| {
+            slice.iter()
+                .map(|s| s.borrow().as_ref().len())
+                .try_fold(n, usize::checked_add)
+        }).expect("attempt to join into collection with len > usize::MAX");
+
+    // crucial for safety
+    let mut result = Vec::with_capacity(len);
+    assert!(result.capacity() >= len);
+
+    result.extend_from_slice(first.borrow().as_ref());
+
+    unsafe {
+        {
+            let pos = result.len();
+            let target = result.get_unchecked_mut(pos..len);
+
+            // copy separator and slices over without bounds checks
+            // generate loops with hardcoded offsets for small separators
+            // massive improvements possible (~ x2)
+            spezialize_for_lengths!(sep, target, iter; 0, 1, 2, 3, 4);
+        }
+        result.set_len(len);
+    }
+    result
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Borrow<str> for String {
     #[inline]
diff --git a/src/liballoc/task.rs b/src/liballoc/task.rs
new file mode 100644
index 0000000..7b1947b
--- /dev/null
+++ b/src/liballoc/task.rs
@@ -0,0 +1,140 @@
+// Copyright 2018 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.
+
+//! Types and Traits for working with asynchronous tasks.
+
+pub use core::task::*;
+
+#[cfg(target_has_atomic = "ptr")]
+pub use self::if_arc::*;
+
+#[cfg(target_has_atomic = "ptr")]
+mod if_arc {
+    use super::*;
+    use arc::Arc;
+    use core::marker::PhantomData;
+    use core::mem;
+    use core::ptr::{self, NonNull};
+
+    /// A way of waking up a specific task.
+    ///
+    /// Any task executor must provide a way of signaling that a task it owns
+    /// is ready to be `poll`ed again. Executors do so by implementing this trait.
+    pub trait Wake: Send + Sync {
+        /// Indicates that the associated task is ready to make progress and should
+        /// be `poll`ed.
+        ///
+        /// Executors generally maintain a queue of "ready" tasks; `wake` should place
+        /// the associated task onto this queue.
+        fn wake(arc_self: &Arc<Self>);
+
+        /// Indicates that the associated task is ready to make progress and should
+        /// be `poll`ed. This function is like `wake`, but can only be called from the
+        /// thread on which this `Wake` was created.
+        ///
+        /// Executors generally maintain a queue of "ready" tasks; `wake_local` should place
+        /// the associated task onto this queue.
+        #[inline]
+        unsafe fn wake_local(arc_self: &Arc<Self>) {
+            Self::wake(arc_self);
+        }
+    }
+
+    #[cfg(target_has_atomic = "ptr")]
+    struct ArcWrapped<T>(PhantomData<T>);
+
+    unsafe impl<T: Wake + 'static> UnsafeWake for ArcWrapped<T> {
+        #[inline]
+        unsafe fn clone_raw(&self) -> Waker {
+            let me: *const ArcWrapped<T> = self;
+            let arc = (*(&me as *const *const ArcWrapped<T> as *const Arc<T>)).clone();
+            Waker::from(arc)
+        }
+
+        #[inline]
+        unsafe fn drop_raw(&self) {
+            let mut me: *const ArcWrapped<T> = self;
+            let me = &mut me as *mut *const ArcWrapped<T> as *mut Arc<T>;
+            ptr::drop_in_place(me);
+        }
+
+        #[inline]
+        unsafe fn wake(&self) {
+            let me: *const ArcWrapped<T> = self;
+            T::wake(&*(&me as *const *const ArcWrapped<T> as *const Arc<T>))
+        }
+
+        #[inline]
+        unsafe fn wake_local(&self) {
+            let me: *const ArcWrapped<T> = self;
+            T::wake_local(&*(&me as *const *const ArcWrapped<T> as *const Arc<T>))
+        }
+    }
+
+    impl<T> From<Arc<T>> for Waker
+        where T: Wake + 'static,
+    {
+        fn from(rc: Arc<T>) -> Self {
+            unsafe {
+                let ptr = mem::transmute::<Arc<T>, NonNull<ArcWrapped<T>>>(rc);
+                Waker::new(ptr)
+            }
+        }
+    }
+
+    /// Creates a `LocalWaker` from a local `wake`.
+    ///
+    /// This function requires that `wake` is "local" (created on the current thread).
+    /// The resulting `LocalWaker` will call `wake.wake_local()` when awoken, and
+    /// will call `wake.wake()` if awoken after being converted to a `Waker`.
+    #[inline]
+    pub unsafe fn local_waker<W: Wake + 'static>(wake: Arc<W>) -> LocalWaker {
+        let ptr = mem::transmute::<Arc<W>, NonNull<ArcWrapped<W>>>(wake);
+        LocalWaker::new(ptr)
+    }
+
+    struct NonLocalAsLocal<T>(ArcWrapped<T>);
+
+    unsafe impl<T: Wake + 'static> UnsafeWake for NonLocalAsLocal<T> {
+        #[inline]
+        unsafe fn clone_raw(&self) -> Waker {
+            self.0.clone_raw()
+        }
+
+        #[inline]
+        unsafe fn drop_raw(&self) {
+            self.0.drop_raw()
+        }
+
+        #[inline]
+        unsafe fn wake(&self) {
+            self.0.wake()
+        }
+
+        #[inline]
+        unsafe fn wake_local(&self) {
+            // Since we're nonlocal, we can't call wake_local
+            self.0.wake()
+        }
+    }
+
+    /// Creates a `LocalWaker` from a non-local `wake`.
+    ///
+    /// This function is similar to `local_waker`, but does not require that `wake`
+    /// is local to the current thread. The resulting `LocalWaker` will call
+    /// `wake.wake()` when awoken.
+    #[inline]
+    pub fn local_waker_from_nonlocal<W: Wake + 'static>(wake: Arc<W>) -> LocalWaker {
+        unsafe {
+            let ptr = mem::transmute::<Arc<W>, NonNull<NonLocalAsLocal<W>>>(wake);
+            LocalWaker::new(ptr)
+        }
+    }
+}
diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs
index 081c473..dbac2c0 100644
--- a/src/liballoc/tests/lib.rs
+++ b/src/liballoc/tests/lib.rs
@@ -15,7 +15,6 @@
 #![feature(const_fn)]
 #![feature(drain_filter)]
 #![feature(exact_size_is_empty)]
-#![feature(iterator_step_by)]
 #![feature(pattern)]
 #![feature(rand)]
 #![feature(slice_sort_by_cached_key)]
diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs
index 6fd0b33..3b7eec3 100644
--- a/src/liballoc/tests/slice.rs
+++ b/src/liballoc/tests/slice.rs
@@ -610,6 +610,15 @@
 }
 
 #[test]
+fn test_join_nocopy() {
+    let v: [String; 0] = [];
+    assert_eq!(v.join(","), "");
+    assert_eq!(["a".to_string(), "ab".into()].join(","), "a,ab");
+    assert_eq!(["a".to_string(), "ab".into(), "abc".into()].join(","), "a,ab,abc");
+    assert_eq!(["a".to_string(), "ab".into(), "".into()].join(","), "a,ab,");
+}
+
+#[test]
 fn test_insert() {
     let mut a = vec![1, 2, 4];
     a.insert(2, 3);
diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs
index d11bf5d..75306ac 100644
--- a/src/liballoc/tests/str.rs
+++ b/src/liballoc/tests/str.rs
@@ -162,6 +162,19 @@
     test_join!("-a-bc", ["", "a", "bc"], "-");
 }
 
+// join has fast paths for small separators up to 4 bytes
+// this tests the slow paths.
+#[test]
+fn test_join_for_different_lengths_with_long_separator() {
+    assert_eq!("~~~~~".len(), 15);
+
+    let empty: &[&str] = &[];
+    test_join!("", empty, "~~~~~");
+    test_join!("a", ["a"], "~~~~~");
+    test_join!("a~~~~~b", ["a", "b"], "~~~~~");
+    test_join!("~~~~~a~~~~~bc", ["", "a", "bc"], "~~~~~");
+}
+
 #[test]
 fn test_unsafe_slice() {
     assert_eq!("ab", unsafe {"abc".slice_unchecked(0, 2)});
@@ -1313,6 +1326,7 @@
 
     t::<&str>();
     t::<String>();
+    t::<&mut str>();
 }
 
 #[test]
diff --git a/src/liballoc_jemalloc/lib.rs b/src/liballoc_jemalloc/lib.rs
index ce856ec..b3b2071 100644
--- a/src/liballoc_jemalloc/lib.rs
+++ b/src/liballoc_jemalloc/lib.rs
@@ -11,9 +11,8 @@
 #![no_std]
 #![allow(unused_attributes)]
 #![unstable(feature = "alloc_jemalloc",
-            reason = "this library is unlikely to be stabilized in its current \
-                      form or name",
-            issue = "27783")]
+            reason = "implementation detail of std, does not provide any public API",
+            issue = "0")]
 #![feature(core_intrinsics)]
 #![feature(libc)]
 #![feature(linkage)]
diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs
index 9490b54..64348e0 100644
--- a/src/liballoc_system/lib.rs
+++ b/src/liballoc_system/lib.rs
@@ -14,7 +14,6 @@
             reason = "this library is unlikely to be stabilized in its current \
                       form or name",
             issue = "32838")]
-#![feature(global_allocator)]
 #![feature(allocator_api)]
 #![feature(core_intrinsics)]
 #![feature(staged_api)]
@@ -41,54 +40,78 @@
 #[allow(dead_code)]
 const MIN_ALIGN: usize = 16;
 
-use core::alloc::{Alloc, GlobalAlloc, AllocErr, Layout, Opaque};
+use core::alloc::{Alloc, GlobalAlloc, AllocErr, Layout};
 use core::ptr::NonNull;
 
-#[unstable(feature = "allocator_api", issue = "32838")]
+/// The default memory allocator provided by the operating system.
+///
+/// This is based on `malloc` on Unix platforms and `HeapAlloc` on Windows,
+/// plus related functions.
+///
+/// This type can be used in a `static` item
+/// with the `#[global_allocator]` attribute
+/// to force the global allocator to be the system’s one.
+/// (The default is jemalloc for executables, on some platforms.)
+///
+/// ```rust
+/// use std::alloc::System;
+///
+/// #[global_allocator]
+/// static A: System = System;
+///
+/// fn main() {
+///     let a = Box::new(4); // Allocates from the system allocator.
+///     println!("{}", a);
+/// }
+/// ```
+///
+/// It can also be used directly to allocate memory
+/// independently of the standard library’s global allocator.
+#[stable(feature = "alloc_system_type", since = "1.28.0")]
 pub struct System;
 
 #[unstable(feature = "allocator_api", issue = "32838")]
 unsafe impl Alloc for System {
     #[inline]
-    unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<Opaque>, AllocErr> {
+    unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
         NonNull::new(GlobalAlloc::alloc(self, layout)).ok_or(AllocErr)
     }
 
     #[inline]
-    unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<Opaque>, AllocErr> {
+    unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
         NonNull::new(GlobalAlloc::alloc_zeroed(self, layout)).ok_or(AllocErr)
     }
 
     #[inline]
-    unsafe fn dealloc(&mut self, ptr: NonNull<Opaque>, layout: Layout) {
+    unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
         GlobalAlloc::dealloc(self, ptr.as_ptr(), layout)
     }
 
     #[inline]
     unsafe fn realloc(&mut self,
-                      ptr: NonNull<Opaque>,
+                      ptr: NonNull<u8>,
                       layout: Layout,
-                      new_size: usize) -> Result<NonNull<Opaque>, AllocErr> {
+                      new_size: usize) -> Result<NonNull<u8>, AllocErr> {
         NonNull::new(GlobalAlloc::realloc(self, ptr.as_ptr(), layout, new_size)).ok_or(AllocErr)
     }
 }
 
 #[cfg(any(windows, unix, target_os = "cloudabi", target_os = "redox"))]
 mod realloc_fallback {
-    use core::alloc::{GlobalAlloc, Opaque, Layout};
+    use core::alloc::{GlobalAlloc, Layout};
     use core::cmp;
     use core::ptr;
 
     impl super::System {
-        pub(crate) unsafe fn realloc_fallback(&self, ptr: *mut Opaque, old_layout: Layout,
-                                              new_size: usize) -> *mut Opaque {
+        pub(crate) unsafe fn realloc_fallback(&self, ptr: *mut u8, old_layout: Layout,
+                                              new_size: usize) -> *mut u8 {
             // Docs for GlobalAlloc::realloc require this to be valid:
             let new_layout = Layout::from_size_align_unchecked(new_size, old_layout.align());
 
             let new_ptr = GlobalAlloc::alloc(self, new_layout);
             if !new_ptr.is_null() {
                 let size = cmp::min(old_layout.size(), new_size);
-                ptr::copy_nonoverlapping(ptr as *mut u8, new_ptr as *mut u8, size);
+                ptr::copy_nonoverlapping(ptr, new_ptr, size);
                 GlobalAlloc::dealloc(self, ptr, old_layout);
             }
             new_ptr
@@ -104,21 +127,19 @@
 
     use MIN_ALIGN;
     use System;
-    use core::alloc::{GlobalAlloc, Layout, Opaque};
+    use core::alloc::{GlobalAlloc, Layout};
 
-    #[unstable(feature = "allocator_api", issue = "32838")]
+    #[stable(feature = "alloc_system_type", since = "1.28.0")]
     unsafe impl GlobalAlloc for System {
         #[inline]
-        unsafe fn alloc(&self, layout: Layout) -> *mut Opaque {
+        unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
             if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
-                libc::malloc(layout.size()) as *mut Opaque
+                libc::malloc(layout.size()) as *mut u8
             } else {
                 #[cfg(target_os = "macos")]
                 {
                     if layout.align() > (1 << 31) {
-                        // FIXME: use Opaque::null_mut
-                        // https://github.com/rust-lang/rust/issues/49659
-                        return 0 as *mut Opaque
+                        return ptr::null_mut()
                     }
                 }
                 aligned_malloc(&layout)
@@ -126,27 +147,27 @@
         }
 
         #[inline]
-        unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut Opaque {
+        unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
             if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
-                libc::calloc(layout.size(), 1) as *mut Opaque
+                libc::calloc(layout.size(), 1) as *mut u8
             } else {
                 let ptr = self.alloc(layout.clone());
                 if !ptr.is_null() {
-                    ptr::write_bytes(ptr as *mut u8, 0, layout.size());
+                    ptr::write_bytes(ptr, 0, layout.size());
                 }
                 ptr
             }
         }
 
         #[inline]
-        unsafe fn dealloc(&self, ptr: *mut Opaque, _layout: Layout) {
+        unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
             libc::free(ptr as *mut libc::c_void)
         }
 
         #[inline]
-        unsafe fn realloc(&self, ptr: *mut Opaque, layout: Layout, new_size: usize) -> *mut Opaque {
+        unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
             if layout.align() <= MIN_ALIGN && layout.align() <= new_size {
-                libc::realloc(ptr as *mut libc::c_void, new_size) as *mut Opaque
+                libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8
             } else {
                 self.realloc_fallback(ptr, layout, new_size)
             }
@@ -155,7 +176,7 @@
 
     #[cfg(any(target_os = "android", target_os = "redox", target_os = "solaris"))]
     #[inline]
-    unsafe fn aligned_malloc(layout: &Layout) -> *mut Opaque {
+    unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
         // On android we currently target API level 9 which unfortunately
         // doesn't have the `posix_memalign` API used below. Instead we use
         // `memalign`, but this unfortunately has the property on some systems
@@ -173,19 +194,18 @@
         // [3]: https://bugs.chromium.org/p/chromium/issues/detail?id=138579
         // [4]: https://chromium.googlesource.com/chromium/src/base/+/master/
         //                                       /memory/aligned_memory.cc
-        libc::memalign(layout.align(), layout.size()) as *mut Opaque
+        libc::memalign(layout.align(), layout.size()) as *mut u8
     }
 
     #[cfg(not(any(target_os = "android", target_os = "redox", target_os = "solaris")))]
     #[inline]
-    unsafe fn aligned_malloc(layout: &Layout) -> *mut Opaque {
+    unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
         let mut out = ptr::null_mut();
         let ret = libc::posix_memalign(&mut out, layout.align(), layout.size());
         if ret != 0 {
-            // FIXME: use Opaque::null_mut https://github.com/rust-lang/rust/issues/49659
-            0 as *mut Opaque
+            ptr::null_mut()
         } else {
-            out as *mut Opaque
+            out as *mut u8
         }
     }
 }
@@ -195,7 +215,7 @@
 mod platform {
     use MIN_ALIGN;
     use System;
-    use core::alloc::{GlobalAlloc, Opaque, Layout};
+    use core::alloc::{GlobalAlloc, Layout};
 
     type LPVOID = *mut u8;
     type HANDLE = LPVOID;
@@ -227,7 +247,7 @@
     }
 
     #[inline]
-    unsafe fn allocate_with_flags(layout: Layout, flags: DWORD) -> *mut Opaque {
+    unsafe fn allocate_with_flags(layout: Layout, flags: DWORD) -> *mut u8 {
         let ptr = if layout.align() <= MIN_ALIGN {
             HeapAlloc(GetProcessHeap(), flags, layout.size())
         } else {
@@ -239,29 +259,29 @@
                 align_ptr(ptr, layout.align())
             }
         };
-        ptr as *mut Opaque
+        ptr as *mut u8
     }
 
-    #[unstable(feature = "allocator_api", issue = "32838")]
+    #[stable(feature = "alloc_system_type", since = "1.28.0")]
     unsafe impl GlobalAlloc for System {
         #[inline]
-        unsafe fn alloc(&self, layout: Layout) -> *mut Opaque {
+        unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
             allocate_with_flags(layout, 0)
         }
 
         #[inline]
-        unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut Opaque {
+        unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
             allocate_with_flags(layout, HEAP_ZERO_MEMORY)
         }
 
         #[inline]
-        unsafe fn dealloc(&self, ptr: *mut Opaque, layout: Layout) {
+        unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
             if layout.align() <= MIN_ALIGN {
                 let err = HeapFree(GetProcessHeap(), 0, ptr as LPVOID);
                 debug_assert!(err != 0, "Failed to free heap memory: {}",
                               GetLastError());
             } else {
-                let header = get_header(ptr as *mut u8);
+                let header = get_header(ptr);
                 let err = HeapFree(GetProcessHeap(), 0, header.0 as LPVOID);
                 debug_assert!(err != 0, "Failed to free heap memory: {}",
                               GetLastError());
@@ -269,9 +289,9 @@
         }
 
         #[inline]
-        unsafe fn realloc(&self, ptr: *mut Opaque, layout: Layout, new_size: usize) -> *mut Opaque {
+        unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
             if layout.align() <= MIN_ALIGN {
-                HeapReAlloc(GetProcessHeap(), 0, ptr as LPVOID, new_size) as *mut Opaque
+                HeapReAlloc(GetProcessHeap(), 0, ptr as LPVOID, new_size) as *mut u8
             } else {
                 self.realloc_fallback(ptr, layout, new_size)
             }
@@ -300,32 +320,32 @@
 mod platform {
     extern crate dlmalloc;
 
-    use core::alloc::{GlobalAlloc, Layout, Opaque};
+    use core::alloc::{GlobalAlloc, Layout};
     use System;
 
     // No need for synchronization here as wasm is currently single-threaded
     static mut DLMALLOC: dlmalloc::Dlmalloc = dlmalloc::DLMALLOC_INIT;
 
-    #[unstable(feature = "allocator_api", issue = "32838")]
+    #[stable(feature = "alloc_system_type", since = "1.28.0")]
     unsafe impl GlobalAlloc for System {
         #[inline]
-        unsafe fn alloc(&self, layout: Layout) -> *mut Opaque {
-            DLMALLOC.malloc(layout.size(), layout.align()) as *mut Opaque
+        unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+            DLMALLOC.malloc(layout.size(), layout.align())
         }
 
         #[inline]
-        unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut Opaque {
-            DLMALLOC.calloc(layout.size(), layout.align()) as *mut Opaque
+        unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
+            DLMALLOC.calloc(layout.size(), layout.align())
         }
 
         #[inline]
-        unsafe fn dealloc(&self, ptr: *mut Opaque, layout: Layout) {
-            DLMALLOC.free(ptr as *mut u8, layout.size(), layout.align())
+        unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
+            DLMALLOC.free(ptr, layout.size(), layout.align())
         }
 
         #[inline]
-        unsafe fn realloc(&self, ptr: *mut Opaque, layout: Layout, new_size: usize) -> *mut Opaque {
-            DLMALLOC.realloc(ptr as *mut u8, layout.size(), layout.align(), new_size) as *mut Opaque
+        unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
+            DLMALLOC.realloc(ptr, layout.size(), layout.align(), new_size)
         }
     }
 }
diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs
index 674c4fb..353688d 100644
--- a/src/libcore/alloc.rs
+++ b/src/libcore/alloc.rs
@@ -8,43 +8,26 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![unstable(feature = "allocator_api",
-            reason = "the precise API and guarantees it provides may be tweaked \
-                      slightly, especially to possibly take into account the \
-                      types being stored to make room for a future \
-                      tracing garbage collector",
-            issue = "32838")]
+//! Memory allocation APIs
+
+#![stable(feature = "alloc_module", since = "1.28.0")]
 
 use cmp;
 use fmt;
 use mem;
 use usize;
 use ptr::{self, NonNull};
+use num::NonZeroUsize;
 
-extern {
-    /// An opaque, unsized type. Used for pointers to allocated memory.
-    ///
-    /// This type can only be used behind a pointer like `*mut Opaque` or `ptr::NonNull<Opaque>`.
-    /// Such pointers are similar to C’s `void*` type.
-    pub type Opaque;
-}
-
-impl Opaque {
-    /// Similar to `std::ptr::null`, which requires `T: Sized`.
-    pub fn null() -> *const Self {
-        0 as _
-    }
-
-    /// Similar to `std::ptr::null_mut`, which requires `T: Sized`.
-    pub fn null_mut() -> *mut Self {
-        0 as _
-    }
-}
+#[unstable(feature = "alloc_internals", issue = "0")]
+#[cfg(stage0)]
+pub type Opaque = u8;
 
 /// Represents the combination of a starting address and
 /// a total capacity of the returned block.
+#[unstable(feature = "allocator_api", issue = "32838")]
 #[derive(Debug)]
-pub struct Excess(pub NonNull<Opaque>, pub usize);
+pub struct Excess(pub NonNull<u8>, pub usize);
 
 fn size_align<T>() -> (usize, usize) {
     (mem::size_of::<T>(), mem::align_of::<T>())
@@ -63,10 +46,11 @@
 /// requests have positive size. A caller to the `Alloc::alloc`
 /// method must either ensure that conditions like this are met, or
 /// use specific allocators with looser requirements.)
+#[stable(feature = "alloc_layout", since = "1.28.0")]
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct Layout {
     // size of the requested block of memory, measured in bytes.
-    size: usize,
+    size_: usize,
 
     // alignment of the requested block of memory, measured in bytes.
     // we ensure that this is always a power-of-two, because API's
@@ -75,17 +59,12 @@
     //
     // (However, we do not analogously require `align >= sizeof(void*)`,
     //  even though that is *also* a requirement of `posix_memalign`.)
-    align: usize,
+    align_: NonZeroUsize,
 }
 
-
-// FIXME: audit default implementations for overflow errors,
-// (potentially switching to overflowing_add and
-//  overflowing_mul as necessary).
-
 impl Layout {
     /// Constructs a `Layout` from a given `size` and `align`,
-    /// or returns `None` if either of the following conditions
+    /// or returns `LayoutErr` if either of the following conditions
     /// are not met:
     ///
     /// * `align` must be a power of two,
@@ -93,6 +72,7 @@
     /// * `size`, when rounded up to the nearest multiple of `align`,
     ///    must not overflow (i.e. the rounded value must be less than
     ///    `usize::MAX`).
+    #[stable(feature = "alloc_layout", since = "1.28.0")]
     #[inline]
     pub fn from_size_align(size: usize, align: usize) -> Result<Self, LayoutErr> {
         if !align.is_power_of_two() {
@@ -126,23 +106,27 @@
     ///
     /// # Safety
     ///
-    /// This function is unsafe as it does not verify that `align` is
-    /// a power-of-two nor `size` aligned to `align` fits within the
-    /// address space (i.e. the `Layout::from_size_align` preconditions).
+    /// This function is unsafe as it does not verify the preconditions from
+    /// [`Layout::from_size_align`](#method.from_size_align).
+    #[stable(feature = "alloc_layout", since = "1.28.0")]
     #[inline]
     pub unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
-        Layout { size: size, align: align }
+        Layout { size_: size, align_: NonZeroUsize::new_unchecked(align) }
     }
 
     /// The minimum size in bytes for a memory block of this layout.
+    #[stable(feature = "alloc_layout", since = "1.28.0")]
     #[inline]
-    pub fn size(&self) -> usize { self.size }
+    pub fn size(&self) -> usize { self.size_ }
 
     /// The minimum byte alignment for a memory block of this layout.
+    #[stable(feature = "alloc_layout", since = "1.28.0")]
     #[inline]
-    pub fn align(&self) -> usize { self.align }
+    pub fn align(&self) -> usize { self.align_.get() }
 
     /// Constructs a `Layout` suitable for holding a value of type `T`.
+    #[stable(feature = "alloc_layout", since = "1.28.0")]
+    #[inline]
     pub fn new<T>() -> Self {
         let (size, align) = size_align::<T>();
         // Note that the align is guaranteed by rustc to be a power of two and
@@ -158,6 +142,8 @@
     /// Produces layout describing a record that could be used to
     /// allocate backing structure for `T` (which could be a trait
     /// or other unsized type like a slice).
+    #[stable(feature = "alloc_layout", since = "1.28.0")]
+    #[inline]
     pub fn for_value<T: ?Sized>(t: &T) -> Self {
         let (size, align) = (mem::size_of_val(t), mem::align_of_val(t));
         // See rationale in `new` for why this us using an unsafe variant below
@@ -181,18 +167,20 @@
     ///
     /// # Panics
     ///
-    /// Panics if the combination of `self.size` and the given `align`
-    /// violates the conditions listed in `from_size_align`.
+    /// Panics if the combination of `self.size()` and the given `align`
+    /// violates the conditions listed in
+    /// [`Layout::from_size_align`](#method.from_size_align).
+    #[unstable(feature = "allocator_api", issue = "32838")]
     #[inline]
     pub fn align_to(&self, align: usize) -> Self {
-        Layout::from_size_align(self.size, cmp::max(self.align, align)).unwrap()
+        Layout::from_size_align(self.size(), cmp::max(self.align(), align)).unwrap()
     }
 
     /// Returns the amount of padding we must insert after `self`
     /// to ensure that the following address will satisfy `align`
     /// (measured in bytes).
     ///
-    /// E.g. if `self.size` is 9, then `self.padding_needed_for(4)`
+    /// E.g. if `self.size()` is 9, then `self.padding_needed_for(4)`
     /// returns 3, because that is the minimum number of bytes of
     /// padding required to get a 4-aligned address (assuming that the
     /// corresponding memory block starts at a 4-aligned address).
@@ -203,7 +191,8 @@
     /// Note that the utility of the returned value requires `align`
     /// to be less than or equal to the alignment of the starting
     /// address for the whole allocated block of memory. One way to
-    /// satisfy this constraint is to ensure `align <= self.align`.
+    /// satisfy this constraint is to ensure `align <= self.align()`.
+    #[unstable(feature = "allocator_api", issue = "32838")]
     #[inline]
     pub fn padding_needed_for(&self, align: usize) -> usize {
         let len = self.size();
@@ -227,7 +216,8 @@
         // size and padding overflow in the above manner should cause
         // the allocator to yield an error anyway.)
 
-        let len_rounded_up = len.wrapping_add(align).wrapping_sub(1) & !align.wrapping_sub(1);
+        let len_rounded_up = len.wrapping_add(align).wrapping_sub(1)
+            & !align.wrapping_sub(1);
         return len_rounded_up.wrapping_sub(len);
     }
 
@@ -238,14 +228,20 @@
     /// layout of the array and `offs` is the distance between the start
     /// of each element in the array.
     ///
-    /// On arithmetic overflow, returns `None`.
+    /// On arithmetic overflow, returns `LayoutErr`.
+    #[unstable(feature = "allocator_api", issue = "32838")]
     #[inline]
     pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutErr> {
-        let padded_size = self.size.checked_add(self.padding_needed_for(self.align))
+        let padded_size = self.size().checked_add(self.padding_needed_for(self.align()))
             .ok_or(LayoutErr { private: () })?;
         let alloc_size = padded_size.checked_mul(n)
             .ok_or(LayoutErr { private: () })?;
-        Ok((Layout::from_size_align(alloc_size, self.align)?, padded_size))
+
+        unsafe {
+            // self.align is already known to be valid and alloc_size has been
+            // padded already.
+            Ok((Layout::from_size_align_unchecked(alloc_size, self.align()), padded_size))
+        }
     }
 
     /// Creates a layout describing the record for `self` followed by
@@ -258,16 +254,16 @@
     /// start of the `next` embedded within the concatenated record
     /// (assuming that the record itself starts at offset 0).
     ///
-    /// On arithmetic overflow, returns `None`.
+    /// On arithmetic overflow, returns `LayoutErr`.
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    #[inline]
     pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutErr> {
-        let new_align = cmp::max(self.align, next.align);
-        let realigned = Layout::from_size_align(self.size, new_align)?;
+        let new_align = cmp::max(self.align(), next.align());
+        let pad = self.padding_needed_for(next.align());
 
-        let pad = realigned.padding_needed_for(next.align);
-
-        let offset = self.size.checked_add(pad)
+        let offset = self.size().checked_add(pad)
             .ok_or(LayoutErr { private: () })?;
-        let new_size = offset.checked_add(next.size)
+        let new_size = offset.checked_add(next.size())
             .ok_or(LayoutErr { private: () })?;
 
         let layout = Layout::from_size_align(new_size, new_align)?;
@@ -285,10 +281,12 @@
     /// guaranteed that all elements in the array will be properly
     /// aligned.
     ///
-    /// On arithmetic overflow, returns `None`.
+    /// On arithmetic overflow, returns `LayoutErr`.
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    #[inline]
     pub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutErr> {
         let size = self.size().checked_mul(n).ok_or(LayoutErr { private: () })?;
-        Layout::from_size_align(size, self.align)
+        Layout::from_size_align(size, self.align())
     }
 
     /// Creates a layout describing the record for `self` followed by
@@ -305,17 +303,21 @@
     ///  signature out of convenience in matching the signature of
     ///  `extend`.)
     ///
-    /// On arithmetic overflow, returns `None`.
+    /// On arithmetic overflow, returns `LayoutErr`.
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    #[inline]
     pub fn extend_packed(&self, next: Self) -> Result<(Self, usize), LayoutErr> {
         let new_size = self.size().checked_add(next.size())
             .ok_or(LayoutErr { private: () })?;
-        let layout = Layout::from_size_align(new_size, self.align)?;
+        let layout = Layout::from_size_align(new_size, self.align())?;
         Ok((layout, self.size()))
     }
 
     /// Creates a layout describing the record for a `[T; n]`.
     ///
-    /// On arithmetic overflow, returns `None`.
+    /// On arithmetic overflow, returns `LayoutErr`.
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    #[inline]
     pub fn array<T>(n: usize) -> Result<Self, LayoutErr> {
         Layout::new::<T>()
             .repeat(n)
@@ -326,28 +328,33 @@
     }
 }
 
-/// The parameters given to `Layout::from_size_align` do not satisfy
-/// its documented constraints.
+/// The parameters given to `Layout::from_size_align`
+/// or some other `Layout` constructor
+/// do not satisfy its documented constraints.
+#[stable(feature = "alloc_layout", since = "1.28.0")]
 #[derive(Clone, PartialEq, Eq, Debug)]
 pub struct LayoutErr {
     private: ()
 }
 
 // (we need this for downstream impl of trait Error)
+#[stable(feature = "alloc_layout", since = "1.28.0")]
 impl fmt::Display for LayoutErr {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         f.write_str("invalid parameters to Layout::from_size_align")
     }
 }
 
-/// The `AllocErr` error specifies whether an allocation failure is
-/// specifically due to resource exhaustion or if it is due to
+/// The `AllocErr` error indicates an allocation failure
+/// that may be due to resource exhaustion or to
 /// something wrong when combining the given input arguments with this
 /// allocator.
+#[unstable(feature = "allocator_api", issue = "32838")]
 #[derive(Clone, PartialEq, Eq, Debug)]
 pub struct AllocErr;
 
 // (we need this for downstream impl of trait Error)
+#[unstable(feature = "allocator_api", issue = "32838")]
 impl fmt::Display for AllocErr {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         f.write_str("memory allocation failed")
@@ -357,9 +364,11 @@
 /// The `CannotReallocInPlace` error is used when `grow_in_place` or
 /// `shrink_in_place` were unable to reuse the given memory block for
 /// a requested layout.
+#[unstable(feature = "allocator_api", issue = "32838")]
 #[derive(Clone, PartialEq, Eq, Debug)]
 pub struct CannotReallocInPlace;
 
+#[unstable(feature = "allocator_api", issue = "32838")]
 impl CannotReallocInPlace {
     pub fn description(&self) -> &str {
         "cannot reallocate allocator's memory in place"
@@ -367,6 +376,7 @@
 }
 
 // (we need this for downstream impl of trait Error)
+#[unstable(feature = "allocator_api", issue = "32838")]
 impl fmt::Display for CannotReallocInPlace {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "{}", self.description())
@@ -374,6 +384,7 @@
 }
 
 /// Augments `AllocErr` with a CapacityOverflow variant.
+// FIXME: should this be in libcore or liballoc?
 #[derive(Clone, PartialEq, Eq, Debug)]
 #[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
 pub enum CollectionAllocErr {
@@ -392,32 +403,142 @@
     }
 }
 
-/// A memory allocator that can be registered to be the one backing `std::alloc::Global`
+#[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
+impl From<LayoutErr> for CollectionAllocErr {
+    #[inline]
+    fn from(_: LayoutErr) -> Self {
+        CollectionAllocErr::CapacityOverflow
+    }
+}
+
+/// A memory allocator that can be registered as the standard library’s default
 /// though the `#[global_allocator]` attributes.
+///
+/// Some of the methods require that a memory block be *currently
+/// allocated* via an allocator. This means that:
+///
+/// * the starting address for that memory block was previously
+///   returned by a previous call to an allocation method
+///   such as `alloc`, and
+///
+/// * the memory block has not been subsequently deallocated, where
+///   blocks are deallocated either by being passed to a deallocation
+///   method such as `dealloc` or by being
+///   passed to a reallocation method that returns a non-null pointer.
+///
+///
+/// # Example
+///
+/// ```no_run
+/// use std::alloc::{GlobalAlloc, Layout, alloc};
+/// use std::ptr::null_mut;
+///
+/// struct MyAllocator;
+///
+/// unsafe impl GlobalAlloc for MyAllocator {
+///     unsafe fn alloc(&self, _layout: Layout) -> *mut u8 { null_mut() }
+///     unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
+/// }
+///
+/// #[global_allocator]
+/// static A: MyAllocator = MyAllocator;
+///
+/// fn main() {
+///     unsafe {
+///         assert!(alloc(Layout::new::<u32>()).is_null())
+///     }
+/// }
+/// ```
+///
+/// # Unsafety
+///
+/// The `GlobalAlloc` trait is an `unsafe` trait for a number of reasons, and
+/// implementors must ensure that they adhere to these contracts:
+///
+/// * It's undefined behavior if global allocators unwind.  This restriction may
+///   be lifted in the future, but currently a panic from any of these
+///   functions may lead to memory unsafety.
+///
+/// * `Layout` queries and calculations in general must be correct. Callers of
+///   this trait are allowed to rely on the contracts defined on each method,
+///   and implementors must ensure such contracts remain true.
+#[stable(feature = "global_alloc", since = "1.28.0")]
 pub unsafe trait GlobalAlloc {
     /// Allocate memory as described by the given `layout`.
     ///
     /// Returns a pointer to newly-allocated memory,
-    /// or NULL to indicate allocation failure.
+    /// or null to indicate allocation failure.
     ///
     /// # Safety
     ///
-    /// **FIXME:** what are the exact requirements?
-    unsafe fn alloc(&self, layout: Layout) -> *mut Opaque;
+    /// This function is unsafe because undefined behavior can result
+    /// if the caller does not ensure that `layout` has non-zero size.
+    ///
+    /// (Extension subtraits might provide more specific bounds on
+    /// behavior, e.g. guarantee a sentinel address or a null pointer
+    /// in response to a zero-size allocation request.)
+    ///
+    /// The allocated block of memory may or may not be initialized.
+    ///
+    /// # Errors
+    ///
+    /// Returning a null pointer indicates that either memory is exhausted
+    /// or `layout` does not meet allocator's size or alignment constraints.
+    ///
+    /// Implementations are encouraged to return null on memory
+    /// exhaustion rather than aborting, but this is not
+    /// a strict requirement. (Specifically: it is *legal* to
+    /// implement this trait atop an underlying native allocation
+    /// library that aborts on memory exhaustion.)
+    ///
+    /// Clients wishing to abort computation in response to an
+    /// allocation error are encouraged to call the [`oom`] function,
+    /// rather than directly invoking `panic!` or similar.
+    ///
+    /// [`oom`]: ../../alloc/alloc/fn.oom.html
+    #[stable(feature = "global_alloc", since = "1.28.0")]
+    unsafe fn alloc(&self, layout: Layout) -> *mut u8;
 
     /// Deallocate the block of memory at the given `ptr` pointer with the given `layout`.
     ///
     /// # Safety
     ///
-    /// **FIXME:** what are the exact requirements?
-    /// In particular around layout *fit*. (See docs for the `Alloc` trait.)
-    unsafe fn dealloc(&self, ptr: *mut Opaque, layout: Layout);
+    /// This function is unsafe because undefined behavior can result
+    /// if the caller does not ensure all of the following:
+    ///
+    /// * `ptr` must denote a block of memory currently allocated via
+    ///   this allocator,
+    ///
+    /// * `layout` must be the same layout that was used
+    ///   to allocated that block of memory,
+    #[stable(feature = "global_alloc", since = "1.28.0")]
+    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout);
 
-    unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut Opaque {
+    /// Behaves like `alloc`, but also ensures that the contents
+    /// are set to zero before being returned.
+    ///
+    /// # Safety
+    ///
+    /// This function is unsafe for the same reasons that `alloc` is.
+    /// However the allocated block of memory is guaranteed to be initialized.
+    ///
+    /// # Errors
+    ///
+    /// Returning a null pointer indicates that either memory is exhausted
+    /// or `layout` does not meet allocator's size or alignment constraints,
+    /// just as in `alloc`.
+    ///
+    /// Clients wishing to abort computation in response to an
+    /// allocation error are encouraged to call the [`oom`] function,
+    /// rather than directly invoking `panic!` or similar.
+    ///
+    /// [`oom`]: ../../alloc/alloc/fn.oom.html
+    #[stable(feature = "global_alloc", since = "1.28.0")]
+    unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
         let size = layout.size();
         let ptr = self.alloc(layout);
         if !ptr.is_null() {
-            ptr::write_bytes(ptr as *mut u8, 0, size);
+            ptr::write_bytes(ptr, 0, size);
         }
         ptr
     }
@@ -425,26 +546,61 @@
     /// Shink or grow a block of memory to the given `new_size`.
     /// The block is described by the given `ptr` pointer and `layout`.
     ///
-    /// Return a new pointer (which may or may not be the same as `ptr`),
-    /// or NULL to indicate reallocation failure.
+    /// If this returns a non-null pointer, then ownership of the memory block
+    /// referenced by `ptr` has been transferred to this alloctor.
+    /// The memory may or may not have been deallocated,
+    /// and should be considered unusable (unless of course it was
+    /// transferred back to the caller again via the return value of
+    /// this method).
     ///
-    /// If reallocation is successful, the old `ptr` pointer is considered
-    /// to have been deallocated.
+    /// If this method returns null, then ownership of the memory
+    /// block has not been transferred to this allocator, and the
+    /// contents of the memory block are unaltered.
     ///
     /// # Safety
     ///
-    /// `new_size`, when rounded up to the nearest multiple of `old_layout.align()`,
-    /// must not overflow (i.e. the rounded value must be less than `usize::MAX`).
+    /// This function is unsafe because undefined behavior can result
+    /// if the caller does not ensure all of the following:
     ///
-    /// **FIXME:** what are the exact requirements?
-    /// In particular around layout *fit*. (See docs for the `Alloc` trait.)
-    unsafe fn realloc(&self, ptr: *mut Opaque, layout: Layout, new_size: usize) -> *mut Opaque {
+    /// * `ptr` must be currently allocated via this allocator,
+    ///
+    /// * `layout` must be the same layout that was used
+    ///   to allocated that block of memory,
+    ///
+    /// * `new_size` must be greater than zero.
+    ///
+    /// * `new_size`, when rounded up to the nearest multiple of `layout.align()`,
+    ///   must not overflow (i.e. the rounded value must be less than `usize::MAX`).
+    ///
+    /// (Extension subtraits might provide more specific bounds on
+    /// behavior, e.g. guarantee a sentinel address or a null pointer
+    /// in response to a zero-size allocation request.)
+    ///
+    /// # Errors
+    ///
+    /// Returns null if the new layout does not meet the size
+    /// and alignment constraints of the allocator, or if reallocation
+    /// otherwise fails.
+    ///
+    /// Implementations are encouraged to return null on memory
+    /// exhaustion rather than panicking or aborting, but this is not
+    /// a strict requirement. (Specifically: it is *legal* to
+    /// implement this trait atop an underlying native allocation
+    /// library that aborts on memory exhaustion.)
+    ///
+    /// Clients wishing to abort computation in response to a
+    /// reallocation error are encouraged to call the [`oom`] function,
+    /// rather than directly invoking `panic!` or similar.
+    ///
+    /// [`oom`]: ../../alloc/alloc/fn.oom.html
+    #[stable(feature = "global_alloc", since = "1.28.0")]
+    unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
         let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());
         let new_ptr = self.alloc(new_layout);
         if !new_ptr.is_null() {
             ptr::copy_nonoverlapping(
-                ptr as *const u8,
-                new_ptr as *mut u8,
+                ptr,
+                new_ptr,
                 cmp::min(layout.size(), new_size),
             );
             self.dealloc(ptr, layout);
@@ -526,27 +682,22 @@
 ///   retain their validity until at least the instance of `Alloc` is dropped
 ///   itself.
 ///
-/// * It's undefined behavior if global allocators unwind.  This restriction may
-///   be lifted in the future, but currently a panic from any of these
-///   functions may lead to memory unsafety. Note that as of the time of this
-///   writing allocators *not* intending to be global allocators can still panic
-///   in their implementation without violating memory safety.
-///
 /// * `Layout` queries and calculations in general must be correct. Callers of
 ///   this trait are allowed to rely on the contracts defined on each method,
 ///   and implementors must ensure such contracts remain true.
 ///
 /// Note that this list may get tweaked over time as clarifications are made in
-/// the future. Additionally global allocators may gain unique requirements for
-/// how to safely implement one in the future as well.
+/// the future.
+#[unstable(feature = "allocator_api", issue = "32838")]
 pub unsafe trait Alloc {
 
-    // (Note: existing allocators have unspecified but well-defined
+    // (Note: some existing allocators have unspecified but well-defined
     // behavior in response to a zero size allocation request ;
     // e.g. in C, `malloc` of 0 will either return a null pointer or a
     // unique pointer, but will not have arbitrary undefined
-    // behavior. Rust should consider revising the alloc::heap crate
-    // to reflect this reality.)
+    // behavior.
+    // However in jemalloc for example,
+    // `mallocx(0)` is documented as undefined behavior.)
 
     /// Returns a pointer meeting the size and alignment guarantees of
     /// `layout`.
@@ -582,9 +733,11 @@
     /// library that aborts on memory exhaustion.)
     ///
     /// Clients wishing to abort computation in response to an
-    /// allocation error are encouraged to call the allocator's `oom`
-    /// method, rather than directly invoking `panic!` or similar.
-    unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<Opaque>, AllocErr>;
+    /// allocation error are encouraged to call the [`oom`] function,
+    /// rather than directly invoking `panic!` or similar.
+    ///
+    /// [`oom`]: ../../alloc/alloc/fn.oom.html
+    unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr>;
 
     /// Deallocate the memory referenced by `ptr`.
     ///
@@ -601,7 +754,7 @@
     /// * In addition to fitting the block of memory `layout`, the
     ///   alignment of the `layout` must match the alignment used
     ///   to allocate that block of memory.
-    unsafe fn dealloc(&mut self, ptr: NonNull<Opaque>, layout: Layout);
+    unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout);
 
     // == ALLOCATOR-SPECIFIC QUANTITIES AND LIMITS ==
     // usable_size
@@ -689,13 +842,15 @@
     /// implement this trait atop an underlying native allocation
     /// library that aborts on memory exhaustion.)
     ///
-    /// Clients wishing to abort computation in response to an
-    /// reallocation error are encouraged to call the allocator's `oom`
-    /// method, rather than directly invoking `panic!` or similar.
+    /// Clients wishing to abort computation in response to a
+    /// reallocation error are encouraged to call the [`oom`] function,
+    /// rather than directly invoking `panic!` or similar.
+    ///
+    /// [`oom`]: ../../alloc/alloc/fn.oom.html
     unsafe fn realloc(&mut self,
-                      ptr: NonNull<Opaque>,
+                      ptr: NonNull<u8>,
                       layout: Layout,
-                      new_size: usize) -> Result<NonNull<Opaque>, AllocErr> {
+                      new_size: usize) -> Result<NonNull<u8>, AllocErr> {
         let old_size = layout.size();
 
         if new_size >= old_size {
@@ -712,8 +867,8 @@
         let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());
         let result = self.alloc(new_layout);
         if let Ok(new_ptr) = result {
-            ptr::copy_nonoverlapping(ptr.as_ptr() as *const u8,
-                                     new_ptr.as_ptr() as *mut u8,
+            ptr::copy_nonoverlapping(ptr.as_ptr(),
+                                     new_ptr.as_ptr(),
                                      cmp::min(old_size, new_size));
             self.dealloc(ptr, layout);
         }
@@ -734,13 +889,15 @@
     /// constraints, just as in `alloc`.
     ///
     /// Clients wishing to abort computation in response to an
-    /// allocation error are encouraged to call the allocator's `oom`
-    /// method, rather than directly invoking `panic!` or similar.
-    unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<Opaque>, AllocErr> {
+    /// allocation error are encouraged to call the [`oom`] function,
+    /// rather than directly invoking `panic!` or similar.
+    ///
+    /// [`oom`]: ../../alloc/alloc/fn.oom.html
+    unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
         let size = layout.size();
         let p = self.alloc(layout);
         if let Ok(p) = p {
-            ptr::write_bytes(p.as_ptr() as *mut u8, 0, size);
+            ptr::write_bytes(p.as_ptr(), 0, size);
         }
         p
     }
@@ -760,8 +917,10 @@
     /// constraints, just as in `alloc`.
     ///
     /// Clients wishing to abort computation in response to an
-    /// allocation error are encouraged to call the allocator's `oom`
-    /// method, rather than directly invoking `panic!` or similar.
+    /// allocation error are encouraged to call the [`oom`] function,
+    /// rather than directly invoking `panic!` or similar.
+    ///
+    /// [`oom`]: ../../alloc/alloc/fn.oom.html
     unsafe fn alloc_excess(&mut self, layout: Layout) -> Result<Excess, AllocErr> {
         let usable_size = self.usable_size(&layout);
         self.alloc(layout).map(|p| Excess(p, usable_size.1))
@@ -781,11 +940,13 @@
     /// `layout` does not meet allocator's size or alignment
     /// constraints, just as in `realloc`.
     ///
-    /// Clients wishing to abort computation in response to an
-    /// reallocation error are encouraged to call the allocator's `oom`
-    /// method, rather than directly invoking `panic!` or similar.
+    /// Clients wishing to abort computation in response to a
+    /// reallocation error are encouraged to call the [`oom`] function,
+    /// rather than directly invoking `panic!` or similar.
+    ///
+    /// [`oom`]: ../../alloc/alloc/fn.oom.html
     unsafe fn realloc_excess(&mut self,
-                             ptr: NonNull<Opaque>,
+                             ptr: NonNull<u8>,
                              layout: Layout,
                              new_size: usize) -> Result<Excess, AllocErr> {
         let new_layout = Layout::from_size_align_unchecked(new_size, layout.align());
@@ -826,15 +987,15 @@
     /// could fit `layout`.
     ///
     /// Note that one cannot pass `CannotReallocInPlace` to the `oom`
-    /// method; clients are expected either to be able to recover from
+    /// function; clients are expected either to be able to recover from
     /// `grow_in_place` failures without aborting, or to fall back on
     /// another reallocation method before resorting to an abort.
     unsafe fn grow_in_place(&mut self,
-                            ptr: NonNull<Opaque>,
+                            ptr: NonNull<u8>,
                             layout: Layout,
                             new_size: usize) -> Result<(), CannotReallocInPlace> {
         let _ = ptr; // this default implementation doesn't care about the actual address.
-        debug_assert!(new_size >= layout.size);
+        debug_assert!(new_size >= layout.size());
         let (_l, u) = self.usable_size(&layout);
         // _l <= layout.size()                       [guaranteed by usable_size()]
         //       layout.size() <= new_layout.size()  [required by this method]
@@ -881,15 +1042,15 @@
     /// could fit `layout`.
     ///
     /// Note that one cannot pass `CannotReallocInPlace` to the `oom`
-    /// method; clients are expected either to be able to recover from
+    /// function; clients are expected either to be able to recover from
     /// `shrink_in_place` failures without aborting, or to fall back
     /// on another reallocation method before resorting to an abort.
     unsafe fn shrink_in_place(&mut self,
-                              ptr: NonNull<Opaque>,
+                              ptr: NonNull<u8>,
                               layout: Layout,
                               new_size: usize) -> Result<(), CannotReallocInPlace> {
         let _ = ptr; // this default implementation doesn't care about the actual address.
-        debug_assert!(new_size <= layout.size);
+        debug_assert!(new_size <= layout.size());
         let (l, _u) = self.usable_size(&layout);
         //                      layout.size() <= _u  [guaranteed by usable_size()]
         // new_layout.size() <= layout.size()        [required by this method]
@@ -929,8 +1090,10 @@
     /// will *not* yield undefined behavior.
     ///
     /// Clients wishing to abort computation in response to an
-    /// allocation error are encouraged to call the allocator's `oom`
-    /// method, rather than directly invoking `panic!` or similar.
+    /// allocation error are encouraged to call the [`oom`] function,
+    /// rather than directly invoking `panic!` or similar.
+    ///
+    /// [`oom`]: ../../alloc/alloc/fn.oom.html
     fn alloc_one<T>(&mut self) -> Result<NonNull<T>, AllocErr>
         where Self: Sized
     {
@@ -964,7 +1127,7 @@
     {
         let k = Layout::new::<T>();
         if k.size() > 0 {
-            self.dealloc(ptr.as_opaque(), k);
+            self.dealloc(ptr.cast(), k);
         }
     }
 
@@ -996,8 +1159,10 @@
     /// Always returns `Err` on arithmetic overflow.
     ///
     /// Clients wishing to abort computation in response to an
-    /// allocation error are encouraged to call the allocator's `oom`
-    /// method, rather than directly invoking `panic!` or similar.
+    /// allocation error are encouraged to call the [`oom`] function,
+    /// rather than directly invoking `panic!` or similar.
+    ///
+    /// [`oom`]: ../../alloc/alloc/fn.oom.html
     fn alloc_array<T>(&mut self, n: usize) -> Result<NonNull<T>, AllocErr>
         where Self: Sized
     {
@@ -1040,9 +1205,11 @@
     ///
     /// Always returns `Err` on arithmetic overflow.
     ///
-    /// Clients wishing to abort computation in response to an
-    /// reallocation error are encouraged to call the allocator's `oom`
-    /// method, rather than directly invoking `panic!` or similar.
+    /// Clients wishing to abort computation in response to a
+    /// reallocation error are encouraged to call the [`oom`] function,
+    /// rather than directly invoking `panic!` or similar.
+    ///
+    /// [`oom`]: ../../alloc/alloc/fn.oom.html
     unsafe fn realloc_array<T>(&mut self,
                                ptr: NonNull<T>,
                                n_old: usize,
@@ -1052,7 +1219,7 @@
         match (Layout::array::<T>(n_old), Layout::array::<T>(n_new)) {
             (Ok(ref k_old), Ok(ref k_new)) if k_old.size() > 0 && k_new.size() > 0 => {
                 debug_assert!(k_old.align() == k_new.align());
-                self.realloc(ptr.as_opaque(), k_old.clone(), k_new.size()).map(NonNull::cast)
+                self.realloc(ptr.cast(), k_old.clone(), k_new.size()).map(NonNull::cast)
             }
             _ => {
                 Err(AllocErr)
@@ -1085,7 +1252,7 @@
     {
         match Layout::array::<T>(n) {
             Ok(ref k) if k.size() > 0 => {
-                Ok(self.dealloc(ptr.as_opaque(), k.clone()))
+                Ok(self.dealloc(ptr.cast(), k.clone()))
             }
             _ => {
                 Err(AllocErr)
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index d50ad58..dd8fce1 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -570,11 +570,20 @@
     }
 }
 
-// Values [1, MAX-1] represent the number of `Ref` active
-// (will not outgrow its range since `usize` is the size of the address space)
+// Values [1, MIN_WRITING-1] represent the number of `Ref` active. Values in
+// [MIN_WRITING, MAX-1] represent the number of `RefMut` active. Multiple
+// `RefMut`s can only be active at a time if they refer to distinct,
+// nonoverlapping components of a `RefCell` (e.g., different ranges of a slice).
+//
+// `Ref` and `RefMut` are both two words in size, and so there will likely never
+// be enough `Ref`s or `RefMut`s in existence to overflow half of the `usize`
+// range. Thus, a `BorrowFlag` will probably never overflow. However, this is
+// not a guarantee, as a pathological program could repeatedly create and then
+// mem::forget `Ref`s or `RefMut`s. Thus, all code must explicitly check for
+// overflow in order to avoid unsafety.
 type BorrowFlag = usize;
 const UNUSED: BorrowFlag = 0;
-const WRITING: BorrowFlag = !0;
+const MIN_WRITING: BorrowFlag = (!0)/2 + 1; // 0b1000...
 
 impl<T> RefCell<T> {
     /// Creates a new `RefCell` containing `value`.
@@ -775,8 +784,9 @@
 
     /// Mutably borrows the wrapped value.
     ///
-    /// The borrow lasts until the returned `RefMut` exits scope. The value
-    /// cannot be borrowed while this borrow is active.
+    /// The borrow lasts until the returned `RefMut` or all `RefMut`s derived
+    /// from it exit scope. The value cannot be borrowed while this borrow is
+    /// active.
     ///
     /// # Panics
     ///
@@ -818,8 +828,9 @@
 
     /// Mutably borrows the wrapped value, returning an error if the value is currently borrowed.
     ///
-    /// The borrow lasts until the returned `RefMut` exits scope. The value cannot be borrowed
-    /// while this borrow is active.
+    /// The borrow lasts until the returned `RefMut` or all `RefMut`s derived
+    /// from it exit scope. The value cannot be borrowed while this borrow is
+    /// active.
     ///
     /// This is the non-panicking variant of [`borrow_mut`](#method.borrow_mut).
     ///
@@ -1010,12 +1021,15 @@
 impl<'b> BorrowRef<'b> {
     #[inline]
     fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRef<'b>> {
-        match borrow.get() {
-            WRITING => None,
-            b => {
-                borrow.set(b + 1);
-                Some(BorrowRef { borrow: borrow })
-            },
+        let b = borrow.get();
+        if b >= MIN_WRITING {
+            None
+        } else {
+            // Prevent the borrow counter from overflowing into
+            // a writing borrow.
+            assert!(b < MIN_WRITING - 1);
+            borrow.set(b + 1);
+            Some(BorrowRef { borrow })
         }
     }
 }
@@ -1024,7 +1038,7 @@
     #[inline]
     fn drop(&mut self) {
         let borrow = self.borrow.get();
-        debug_assert!(borrow != WRITING && borrow != UNUSED);
+        debug_assert!(borrow < MIN_WRITING && borrow != UNUSED);
         self.borrow.set(borrow - 1);
     }
 }
@@ -1036,8 +1050,9 @@
         // is not set to WRITING.
         let borrow = self.borrow.get();
         debug_assert!(borrow != UNUSED);
-        // Prevent the borrow counter from overflowing.
-        assert!(borrow != WRITING);
+        // Prevent the borrow counter from overflowing into
+        // a writing borrow.
+        assert!(borrow < MIN_WRITING - 1);
         self.borrow.set(borrow + 1);
         BorrowRef { borrow: self.borrow }
     }
@@ -1109,6 +1124,37 @@
             borrow: orig.borrow,
         }
     }
+
+    /// Split a `Ref` into multiple `Ref`s for different components of the
+    /// borrowed data.
+    ///
+    /// The `RefCell` is already immutably borrowed, so this cannot fail.
+    ///
+    /// This is an associated function that needs to be used as
+    /// `Ref::map_split(...)`. A method would interfere with methods of the same
+    /// name on the contents of a `RefCell` used through `Deref`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(refcell_map_split)]
+    /// use std::cell::{Ref, RefCell};
+    ///
+    /// let cell = RefCell::new([1, 2, 3, 4]);
+    /// let borrow = cell.borrow();
+    /// let (begin, end) = Ref::map_split(borrow, |slice| slice.split_at(2));
+    /// assert_eq!(*begin, [1, 2]);
+    /// assert_eq!(*end, [3, 4]);
+    /// ```
+    #[unstable(feature = "refcell_map_split", issue = "51476")]
+    #[inline]
+    pub fn map_split<U: ?Sized, V: ?Sized, F>(orig: Ref<'b, T>, f: F) -> (Ref<'b, U>, Ref<'b, V>)
+        where F: FnOnce(&T) -> (&U, &V)
+    {
+        let (a, b) = f(orig.value);
+        let borrow = orig.borrow.clone();
+        (Ref { value: a, borrow }, Ref { value: b, borrow: orig.borrow })
+    }
 }
 
 #[unstable(feature = "coerce_unsized", issue = "27732")]
@@ -1157,6 +1203,44 @@
             borrow: borrow,
         }
     }
+
+    /// Split a `RefMut` into multiple `RefMut`s for different components of the
+    /// borrowed data.
+    ///
+    /// The underlying `RefCell` will remain mutably borrowed until both
+    /// returned `RefMut`s go out of scope.
+    ///
+    /// The `RefCell` is already mutably borrowed, so this cannot fail.
+    ///
+    /// This is an associated function that needs to be used as
+    /// `RefMut::map_split(...)`. A method would interfere with methods of the
+    /// same name on the contents of a `RefCell` used through `Deref`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(refcell_map_split)]
+    /// use std::cell::{RefCell, RefMut};
+    ///
+    /// let cell = RefCell::new([1, 2, 3, 4]);
+    /// let borrow = cell.borrow_mut();
+    /// let (mut begin, mut end) = RefMut::map_split(borrow, |slice| slice.split_at_mut(2));
+    /// assert_eq!(*begin, [1, 2]);
+    /// assert_eq!(*end, [3, 4]);
+    /// begin.copy_from_slice(&[4, 3]);
+    /// end.copy_from_slice(&[2, 1]);
+    /// ```
+    #[unstable(feature = "refcell_map_split", issue = "51476")]
+    #[inline]
+    pub fn map_split<U: ?Sized, V: ?Sized, F>(
+        orig: RefMut<'b, T>, f: F
+    ) -> (RefMut<'b, U>, RefMut<'b, V>)
+        where F: FnOnce(&mut T) -> (&mut U, &mut V)
+    {
+        let (a, b) = f(orig.value);
+        let borrow = orig.borrow.clone();
+        (RefMut { value: a, borrow }, RefMut { value: b, borrow: orig.borrow })
+    }
 }
 
 struct BorrowRefMut<'b> {
@@ -1167,22 +1251,45 @@
     #[inline]
     fn drop(&mut self) {
         let borrow = self.borrow.get();
-        debug_assert!(borrow == WRITING);
-        self.borrow.set(UNUSED);
+        debug_assert!(borrow >= MIN_WRITING);
+        self.borrow.set(if borrow == MIN_WRITING {
+            UNUSED
+        } else {
+            borrow - 1
+        });
     }
 }
 
 impl<'b> BorrowRefMut<'b> {
     #[inline]
     fn new(borrow: &'b Cell<BorrowFlag>) -> Option<BorrowRefMut<'b>> {
+        // NOTE: Unlike BorrowRefMut::clone, new is called to create the initial
+        // mutable reference, and so there must currently be no existing
+        // references. Thus, while clone increments the mutable refcount, here
+        // we simply go directly from UNUSED to MIN_WRITING.
         match borrow.get() {
             UNUSED => {
-                borrow.set(WRITING);
+                borrow.set(MIN_WRITING);
                 Some(BorrowRefMut { borrow: borrow })
             },
             _ => None,
         }
     }
+
+    // Clone a `BorrowRefMut`.
+    //
+    // This is only valid if each `BorrowRefMut` is used to track a mutable
+    // reference to a distinct, nonoverlapping range of the original object.
+    // This isn't in a Clone impl so that code doesn't call this implicitly.
+    #[inline]
+    fn clone(&self) -> BorrowRefMut<'b> {
+        let borrow = self.borrow.get();
+        debug_assert!(borrow >= MIN_WRITING);
+        // Prevent the borrow counter from overflowing.
+        assert!(borrow != !0);
+        self.borrow.set(borrow + 1);
+        BorrowRefMut { borrow: self.borrow }
+    }
 }
 
 /// A wrapper type for a mutably borrowed value from a `RefCell<T>`.
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 0515eee..d91bf46 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -1436,8 +1436,7 @@
     /// ```
     /// extern crate core;
     ///
-    /// use std::fmt;
-    /// use core::fmt::Alignment;
+    /// use std::fmt::{self, Alignment};
     ///
     /// struct Foo;
     ///
diff --git a/src/libcore/future.rs b/src/libcore/future.rs
new file mode 100644
index 0000000..a8c8f69
--- /dev/null
+++ b/src/libcore/future.rs
@@ -0,0 +1,110 @@
+// Copyright 2018 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.
+
+#![unstable(feature = "futures_api",
+            reason = "futures in libcore are unstable",
+            issue = "50547")]
+
+//! Asynchronous values.
+
+use mem::PinMut;
+use marker::Unpin;
+use task::{self, Poll};
+
+/// A future represents an asychronous computation.
+///
+/// A future is a value that may not have finished computing yet. This kind of
+/// "asynchronous value" makes it possible for a thread to continue doing useful
+/// work while it waits for the value to become available.
+///
+/// # The `poll` method
+///
+/// The core method of future, `poll`, *attempts* to resolve the future into a
+/// final value. This method does not block if the value is not ready. Instead,
+/// the current task is scheduled to be woken up when it's possible to make
+/// further progress by `poll`ing again. The wake up is performed using
+/// `cx.waker()`, a handle for waking up the current task.
+///
+/// When using a future, you generally won't call `poll` directly, but instead
+/// `await!` the value.
+pub trait Future {
+    /// The result of the `Future`.
+    type Output;
+
+    /// Attempt to resolve the future to a final value, registering
+    /// the current task for wakeup if the value is not yet available.
+    ///
+    /// # Return value
+    ///
+    /// This function returns:
+    ///
+    /// - `Poll::Pending` if the future is not ready yet
+    /// - `Poll::Ready(val)` with the result `val` of this future if it finished
+    /// successfully.
+    ///
+    /// Once a future has finished, clients should not `poll` it again.
+    ///
+    /// When a future is not ready yet, `poll` returns
+    /// [`Poll::Pending`](::task::Poll). The future will *also* register the
+    /// interest of the current task in the value being produced. For example,
+    /// if the future represents the availability of data on a socket, then the
+    /// task is recorded so that when data arrives, it is woken up (via
+    /// [`cx.waker()`](::task::Context::waker)). Once a task has been woken up,
+    /// it should attempt to `poll` the future again, which may or may not
+    /// produce a final value.
+    ///
+    /// Note that if `Pending` is returned it only means that the *current* task
+    /// (represented by the argument `cx`) will receive a notification. Tasks
+    /// from previous calls to `poll` will *not* receive notifications.
+    ///
+    /// # Runtime characteristics
+    ///
+    /// Futures alone are *inert*; they must be *actively* `poll`ed to make
+    /// progress, meaning that each time the current task is woken up, it should
+    /// actively re-`poll` pending futures that it still has an interest in.
+    ///
+    /// The `poll` function is not called repeatedly in a tight loop for
+    /// futures, but only whenever the future itself is ready, as signaled via
+    /// the `Waker` inside `task::Context`. If you're familiar with the
+    /// `poll(2)` or `select(2)` syscalls on Unix it's worth noting that futures
+    /// typically do *not* suffer the same problems of "all wakeups must poll
+    /// all events"; they are more like `epoll(4)`.
+    ///
+    /// An implementation of `poll` should strive to return quickly, and must
+    /// *never* block. Returning quickly prevents unnecessarily clogging up
+    /// threads or event loops. If it is known ahead of time that a call to
+    /// `poll` may end up taking awhile, the work should be offloaded to a
+    /// thread pool (or something similar) to ensure that `poll` can return
+    /// quickly.
+    ///
+    /// # Panics
+    ///
+    /// Once a future has completed (returned `Ready` from `poll`),
+    /// then any future calls to `poll` may panic, block forever, or otherwise
+    /// cause bad behavior. The `Future` trait itself provides no guarantees
+    /// about the behavior of `poll` after a future has completed.
+    fn poll(self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output>;
+}
+
+impl<'a, F: ?Sized + Future + Unpin> Future for &'a mut F {
+    type Output = F::Output;
+
+    fn poll(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
+        F::poll(PinMut::new(&mut **self), cx)
+    }
+}
+
+impl<'a, F: ?Sized + Future> Future for PinMut<'a, F> {
+    type Output = F::Output;
+
+    fn poll(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
+        F::poll((*self).reborrow(), cx)
+    }
+}
diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs
index 3e1f21c..e6f8dff 100644
--- a/src/libcore/hash/mod.rs
+++ b/src/libcore/hash/mod.rs
@@ -603,6 +603,13 @@
         }
     }
 
+    #[stable(feature = "never_hash", since = "1.29.0")]
+    impl Hash for ! {
+        fn hash<H: Hasher>(&self, _: &mut H) {
+            *self
+        }
+    }
+
     macro_rules! impl_hash_tuple {
         () => (
             #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs
index f5b23a3..81150bc 100644
--- a/src/libcore/iter/iterator.rs
+++ b/src/libcore/iter/iterator.rs
@@ -11,7 +11,7 @@
 use cmp::Ordering;
 use ops::Try;
 
-use super::{AlwaysOk, LoopState};
+use super::LoopState;
 use super::{Chain, Cycle, Cloned, Enumerate, Filter, FilterMap, Fuse};
 use super::{Flatten, FlatMap, flatten_compat};
 use super::{Inspect, Map, Peekable, Scan, Skip, SkipWhile, StepBy, Take, TakeWhile, Rev};
@@ -283,7 +283,6 @@
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(iterator_step_by)]
     /// let a = [0, 1, 2, 3, 4, 5];
     /// let mut iter = a.into_iter().step_by(2);
     ///
@@ -293,9 +292,7 @@
     /// assert_eq!(iter.next(), None);
     /// ```
     #[inline]
-    #[unstable(feature = "iterator_step_by",
-               reason = "unstable replacement of Range::step_by",
-               issue = "27741")]
+    #[stable(feature = "iterator_step_by", since = "1.28.0")]
     fn step_by(self, step: usize) -> StepBy<Self> where Self: Sized {
         assert!(step != 0);
         StepBy{iter: self, step: step - 1, first_take: true}
@@ -1617,7 +1614,7 @@
     fn fold<B, F>(mut self, init: B, mut f: F) -> B where
         Self: Sized, F: FnMut(B, Self::Item) -> B,
     {
-        self.try_fold(init, move |acc, x| AlwaysOk(f(acc, x))).0
+        self.try_fold(init, move |acc, x| Ok::<B, !>(f(acc, x))).unwrap()
     }
 
     /// Tests if every element of the iterator matches a predicate.
diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs
index 1e8476d..840d45f 100644
--- a/src/libcore/iter/mod.rs
+++ b/src/libcore/iter/mod.rs
@@ -333,7 +333,7 @@
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::sources::{Repeat, repeat};
-#[unstable(feature = "iterator_repeat_with", issue = "48169")]
+#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
 pub use self::sources::{RepeatWith, repeat_with};
 #[stable(feature = "iter_empty", since = "1.2.0")]
 pub use self::sources::{Empty, empty};
@@ -354,21 +354,6 @@
 mod sources;
 mod traits;
 
-/// Transparent newtype used to implement foo methods in terms of try_foo.
-/// Important until #43278 is fixed; might be better as `Result<T, !>` later.
-struct AlwaysOk<T>(pub T);
-
-impl<T> Try for AlwaysOk<T> {
-    type Ok = T;
-    type Error = !;
-    #[inline]
-    fn into_result(self) -> Result<Self::Ok, Self::Error> { Ok(self.0) }
-    #[inline]
-    fn from_error(v: Self::Error) -> Self { v }
-    #[inline]
-    fn from_ok(v: Self::Ok) -> Self { AlwaysOk(v) }
-}
-
 /// Used to make try_fold closures more like normal loops
 #[derive(PartialEq)]
 enum LoopState<C, B> {
@@ -673,9 +658,7 @@
 /// [`step_by`]: trait.Iterator.html#method.step_by
 /// [`Iterator`]: trait.Iterator.html
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
-#[unstable(feature = "iterator_step_by",
-           reason = "unstable replacement of Range::step_by",
-           issue = "27741")]
+#[stable(feature = "iterator_step_by", since = "1.28.0")]
 #[derive(Clone, Debug)]
 pub struct StepBy<I> {
     iter: I,
@@ -683,9 +666,7 @@
     first_take: bool,
 }
 
-#[unstable(feature = "iterator_step_by",
-           reason = "unstable replacement of Range::step_by",
-           issue = "27741")]
+#[stable(feature = "iterator_step_by", since = "1.28.0")]
 impl<I> Iterator for StepBy<I> where I: Iterator {
     type Item = I::Item;
 
@@ -757,9 +738,7 @@
 }
 
 // StepBy can only make the iterator shorter, so the len will still fit.
-#[unstable(feature = "iterator_step_by",
-           reason = "unstable replacement of Range::step_by",
-           issue = "27741")]
+#[stable(feature = "iterator_step_by", since = "1.28.0")]
 impl<I> ExactSizeIterator for StepBy<I> where I: ExactSizeIterator {}
 
 /// An iterator that strings two iterators together.
diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs
index 0fc1a3a..d500cc9 100644
--- a/src/libcore/iter/sources.rs
+++ b/src/libcore/iter/sources.rs
@@ -113,12 +113,12 @@
 ///
 /// [`repeat_with`]: fn.repeat_with.html
 #[derive(Copy, Clone, Debug)]
-#[unstable(feature = "iterator_repeat_with", issue = "48169")]
+#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
 pub struct RepeatWith<F> {
     repeater: F
 }
 
-#[unstable(feature = "iterator_repeat_with", issue = "48169")]
+#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
 impl<A, F: FnMut() -> A> Iterator for RepeatWith<F> {
     type Item = A;
 
@@ -129,13 +129,7 @@
     fn size_hint(&self) -> (usize, Option<usize>) { (usize::MAX, None) }
 }
 
-#[unstable(feature = "iterator_repeat_with", issue = "48169")]
-impl<A, F: FnMut() -> A> DoubleEndedIterator for RepeatWith<F> {
-    #[inline]
-    fn next_back(&mut self) -> Option<A> { self.next() }
-}
-
-#[unstable(feature = "iterator_repeat_with", issue = "48169")]
+#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
 impl<A, F: FnMut() -> A> FusedIterator for RepeatWith<F> {}
 
 #[unstable(feature = "trusted_len", issue = "37572")]
@@ -158,19 +152,15 @@
 ///
 /// [`repeat`]: fn.repeat.html
 ///
-/// An iterator produced by `repeat_with()` is a `DoubleEndedIterator`.
-/// It is important to note that reversing `repeat_with(f)` will produce
-/// the exact same sequence as the non-reversed iterator. In other words,
-/// `repeat_with(f).rev().collect::<Vec<_>>()` is equivalent to
-/// `repeat_with(f).collect::<Vec<_>>()`.
+/// An iterator produced by `repeat_with()` is not a `DoubleEndedIterator`.
+/// If you need `repeat_with()` to return a `DoubleEndedIterator`,
+/// please open a GitHub issue explaining your use case.
 ///
 /// # Examples
 ///
 /// Basic usage:
 ///
 /// ```
-/// #![feature(iterator_repeat_with)]
-///
 /// use std::iter;
 ///
 /// // let's assume we have some value of a type that is not `Clone`
@@ -191,8 +181,6 @@
 /// Using mutation and going finite:
 ///
 /// ```rust
-/// #![feature(iterator_repeat_with)]
-///
 /// use std::iter;
 ///
 /// // From the zeroth to the third power of two:
@@ -209,7 +197,7 @@
 /// assert_eq!(None, pow2.next());
 /// ```
 #[inline]
-#[unstable(feature = "iterator_repeat_with", issue = "48169")]
+#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
 pub fn repeat_with<A, F: FnMut() -> A>(repeater: F) -> RepeatWith<F> {
     RepeatWith { repeater }
 }
diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs
index 1551429..3d2ce9e 100644
--- a/src/libcore/iter/traits.rs
+++ b/src/libcore/iter/traits.rs
@@ -10,7 +10,7 @@
 use ops::{Mul, Add, Try};
 use num::Wrapping;
 
-use super::{AlwaysOk, LoopState};
+use super::LoopState;
 
 /// Conversion from an `Iterator`.
 ///
@@ -524,7 +524,7 @@
     fn rfold<B, F>(mut self, accum: B, mut f: F) -> B where
         Self: Sized, F: FnMut(B, Self::Item) -> B,
     {
-        self.try_rfold(accum, move |acc, x| AlwaysOk(f(acc, x))).0
+        self.try_rfold(accum, move |acc, x| Ok::<B, !>(f(acc, x))).unwrap()
     }
 
     /// Searches for an element of an iterator from the back that satisfies a predicate.
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 32cf312..40caee8 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -41,7 +41,7 @@
 //!   dictate the panic message, the file at which panic was invoked, and the
 //!   line and column inside the file. It is up to consumers of this core
 //!   library to define this panic function; it is only required to never
-//!   return. This requires a `lang` attribute named `panic_fmt`.
+//!   return. This requires a `lang` attribute named `panic_impl`.
 //!
 //! * `rust_eh_personality` - is used by the failure mechanisms of the
 //!    compiler. This is often mapped to GCC's personality function, but crates
@@ -81,6 +81,7 @@
 #![feature(cfg_target_has_atomic)]
 #![feature(concat_idents)]
 #![feature(const_fn)]
+#![feature(const_int_ops)]
 #![feature(core_float)]
 #![feature(custom_attribute)]
 #![feature(doc_cfg)]
@@ -89,7 +90,6 @@
 #![feature(fundamental)]
 #![feature(intrinsics)]
 #![feature(iterator_flatten)]
-#![feature(iterator_repeat_with)]
 #![feature(lang_items)]
 #![feature(link_llvm_intrinsics)]
 #![feature(never_type)]
@@ -100,6 +100,7 @@
 #![feature(optin_builtin_traits)]
 #![feature(prelude_import)]
 #![feature(repr_simd, platform_intrinsics)]
+#![cfg_attr(stage0, feature(repr_transparent))]
 #![feature(rustc_attrs)]
 #![feature(rustc_const_unstable)]
 #![feature(simd_ffi)]
@@ -206,17 +207,14 @@
 
 pub mod unicode;
 
+/* Async */
+pub mod future;
+pub mod task;
+
 /* Heap memory allocator trait */
 #[allow(missing_docs)]
 pub mod alloc;
 
-#[unstable(feature = "allocator_api", issue = "32838")]
-#[rustc_deprecated(since = "1.27.0", reason = "module renamed to `alloc`")]
-/// Use the `alloc` module instead.
-pub mod heap {
-    pub use alloc::*;
-}
-
 // note: does not need to be public
 mod iter_private;
 mod nonzero;
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 77db165..3d3f63e 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -294,7 +294,7 @@
 /// This trait is automatically implemented when the compiler determines
 /// it's appropriate.
 ///
-/// The precise definition is: a type `T` is `Sync` if `&T` is
+/// The precise definition is: a type `T` is `Sync` if and only if `&T` is
 /// [`Send`][send]. In other words, if there is no possibility of
 /// [undefined behavior][ub] (including data races) when passing
 /// `&T` references between threads.
diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs
index c033b67..31635ff 100644
--- a/src/libcore/mem.rs
+++ b/src/libcore/mem.rs
@@ -194,10 +194,12 @@
 /// u16 | 2
 /// u32 | 4
 /// u64 | 8
+/// u128 | 16
 /// i8 | 1
 /// i16 | 2
 /// i32 | 4
 /// i64 | 8
+/// i128 | 16
 /// f32 | 4
 /// f64 | 8
 /// char | 4
@@ -635,8 +637,9 @@
     }
 }
 
-/// Replaces the value at a mutable location with a new one, returning the old value, without
-/// deinitializing either one.
+/// Moves `src` into the referenced `dest`, returning the previous `dest` value.
+///
+/// Neither value is dropped.
 ///
 /// # Examples
 ///
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index e5dbc65..577c823 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -31,7 +31,11 @@
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const DIGITS: u32 = 6;
 
-/// Difference between `1.0` and the next largest representable number.
+/// [Machine epsilon] value for `f32`.
+///
+/// This is the difference between `1.0` and the next largest representable number.
+///
+/// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const EPSILON: f32 = 1.19209290e-07_f32;
 
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index eb769c4..b8e3dd6 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -31,7 +31,11 @@
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const DIGITS: u32 = 15;
 
-/// Difference between `1.0` and the next largest representable number.
+/// [Machine epsilon] value for `f64`.
+///
+/// This is the difference between `1.0` and the next largest representable number.
+///
+/// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const EPSILON: f64 = 2.2204460492503131e-16_f64;
 
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 013d033..1168126 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -39,10 +39,10 @@
         $(
             /// An integer that is known not to equal zero.
             ///
-            /// This may enable some memory layout optimization such as:
+            /// This enables some memory layout optimization.
+            /// For example, `Option<NonZeroU32>` is the same size as `u32`:
             ///
             /// ```rust
-            /// # #![feature(nonzero)]
             /// use std::mem::size_of;
             /// assert_eq!(size_of::<Option<std::num::NonZeroU32>>(), size_of::<u32>());
             /// ```
@@ -267,6 +267,16 @@
 ```
 "),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
         }
@@ -282,6 +292,18 @@
 ", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value().count_zeros(), 1);", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn count_zeros(self) -> u32 {
+                (!self).count_ones()
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentatio"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn count_zeros(self) -> u32 {
                 (!self).count_ones()
@@ -302,6 +324,18 @@
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn leading_zeros(self) -> u32 {
+                (self as $UnsignedT).leading_zeros()
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn leading_zeros(self) -> u32 {
                 (self as $UnsignedT).leading_zeros()
@@ -322,6 +356,18 @@
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn trailing_zeros(self) -> u32 {
+                (self as $UnsignedT).trailing_zeros()
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn trailing_zeros(self) -> u32 {
                 (self as $UnsignedT).trailing_zeros()
@@ -396,6 +442,16 @@
         /// assert_eq!(m, 21760);
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
+        #[cfg(not(stage0))]
+        #[rustc_const_unstable(feature = "const_int_ops")]
+        #[inline]
+        pub const fn swap_bytes(self) -> Self {
+            (self as $UnsignedT).swap_bytes() as Self
+        }
+
+        /// Dummy docs. See !stage0 documentation.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[cfg(stage0)]
         #[inline]
         pub fn swap_bytes(self) -> Self {
             (self as $UnsignedT).swap_bytes() as Self
@@ -447,6 +503,25 @@
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn from_be(x: Self) -> Self {
+                #[cfg(target_endian = "big")]
+                {
+                    x
+                }
+                #[cfg(not(target_endian = "big"))]
+                {
+                    x.swap_bytes()
+                }
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn from_be(x: Self) -> Self {
                 if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
@@ -473,6 +548,25 @@
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn from_le(x: Self) -> Self {
+                #[cfg(target_endian = "little")]
+                {
+                    x
+                }
+                #[cfg(not(target_endian = "little"))]
+                {
+                    x.swap_bytes()
+                }
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn from_le(x: Self) -> Self {
                 if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
@@ -499,6 +593,25 @@
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn to_be(self) -> Self { // or not to be?
+                #[cfg(target_endian = "big")]
+                {
+                    self
+                }
+                #[cfg(not(target_endian = "big"))]
+                {
+                    self.swap_bytes()
+                }
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn to_be(self) -> Self { // or not to be?
                 if cfg!(target_endian = "big") { self } else { self.swap_bytes() }
@@ -525,6 +638,25 @@
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn to_le(self) -> Self {
+                #[cfg(target_endian = "little")]
+                {
+                    self
+                }
+                #[cfg(not(target_endian = "little"))]
+                {
+                    self.swap_bytes()
+                }
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn to_le(self) -> Self {
                 if cfg!(target_endian = "little") { self } else { self.swap_bytes() }
@@ -1943,6 +2075,19 @@
     int_impl! { isize, i64, u64, 64, -9223372036854775808, 9223372036854775807, "", "" }
 }
 
+// Emits the correct `cttz` call, depending on the size of the type.
+macro_rules! uint_cttz_call {
+    // As of LLVM 3.6 the codegen for the zero-safe cttz8 intrinsic
+    // emits two conditional moves on x86_64. By promoting the value to
+    // u16 and setting bit 8, we get better code without any conditional
+    // operations.
+    // FIXME: There's a LLVM patch (http://reviews.llvm.org/D9284)
+    // pending, remove this workaround once LLVM generates better code
+    // for cttz8.
+    ($value:expr, 8) => { intrinsics::cttz($value as u16 | 0x100) };
+    ($value:expr, $_BITS:expr) => { intrinsics::cttz($value) }
+}
+
 // `Int` + `UnsignedInt` implemented for unsigned integers
 macro_rules! uint_impl {
     ($SelfT:ty, $ActualT:ty, $BITS:expr, $MaxV:expr, $Feature:expr, $EndFeature:expr) => {
@@ -2020,6 +2165,18 @@
 assert_eq!(n.count_ones(), 3);", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn count_ones(self) -> u32 {
+                unsafe { intrinsics::ctpop(self as $ActualT) as u32 }
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn count_ones(self) -> u32 {
                 unsafe { intrinsics::ctpop(self as $ActualT) as u32 }
@@ -2037,6 +2194,18 @@
 ", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value().count_zeros(), 0);", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn count_zeros(self) -> u32 {
+                (!self).count_ones()
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn count_zeros(self) -> u32 {
                 (!self).count_ones()
@@ -2056,6 +2225,18 @@
 assert_eq!(n.leading_zeros(), 2);", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn leading_zeros(self) -> u32 {
+                unsafe { intrinsics::ctlz(self as $ActualT) as u32 }
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn leading_zeros(self) -> u32 {
                 unsafe { intrinsics::ctlz(self as $ActualT) as u32 }
@@ -2076,22 +2257,21 @@
 assert_eq!(n.trailing_zeros(), 3);", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn trailing_zeros(self) -> u32 {
+                unsafe { uint_cttz_call!(self, $BITS) as u32 }
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn trailing_zeros(self) -> u32 {
-                // As of LLVM 3.6 the codegen for the zero-safe cttz8 intrinsic
-                // emits two conditional moves on x86_64. By promoting the value to
-                // u16 and setting bit 8, we get better code without any conditional
-                // operations.
-                // FIXME: There's a LLVM patch (http://reviews.llvm.org/D9284)
-                // pending, remove this workaround once LLVM generates better code
-                // for cttz8.
-                unsafe {
-                    if $BITS == 8 {
-                        intrinsics::cttz(self as u16 | 0x100) as u32
-                    } else {
-                        intrinsics::cttz(self) as u32
-                    }
-                }
+                unsafe { uint_cttz_call!(self, $BITS) as u32 }
             }
         }
 
@@ -2167,6 +2347,16 @@
         /// assert_eq!(m, 21760);
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
+        #[cfg(not(stage0))]
+        #[rustc_const_unstable(feature = "const_int_ops")]
+        #[inline]
+        pub const fn swap_bytes(self) -> Self {
+            unsafe { intrinsics::bswap(self as $ActualT) as Self }
+        }
+
+        /// Dummy docs. See !stage0 documentation.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[cfg(stage0)]
         #[inline]
         pub fn swap_bytes(self) -> Self {
             unsafe { intrinsics::bswap(self as $ActualT) as Self }
@@ -2218,6 +2408,25 @@
 }", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn from_be(x: Self) -> Self {
+                #[cfg(target_endian = "big")]
+                {
+                    x
+                }
+                #[cfg(not(target_endian = "big"))]
+                {
+                    x.swap_bytes()
+                }
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn from_be(x: Self) -> Self {
                 if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
@@ -2244,6 +2453,25 @@
 }", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn from_le(x: Self) -> Self {
+                #[cfg(target_endian = "little")]
+                {
+                    x
+                }
+                #[cfg(not(target_endian = "little"))]
+                {
+                    x.swap_bytes()
+                }
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn from_le(x: Self) -> Self {
                 if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
@@ -2270,6 +2498,25 @@
 }", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn to_be(self) -> Self { // or not to be?
+                #[cfg(target_endian = "big")]
+                {
+                    self
+                }
+                #[cfg(not(target_endian = "big"))]
+                {
+                    self.swap_bytes()
+                }
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn to_be(self) -> Self { // or not to be?
                 if cfg!(target_endian = "big") { self } else { self.swap_bytes() }
@@ -2296,6 +2543,25 @@
 }", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn to_le(self) -> Self {
+                #[cfg(target_endian = "little")]
+                {
+                    self
+                }
+                #[cfg(not(target_endian = "little"))]
+                {
+                    self.swap_bytes()
+                }
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn to_le(self) -> Self {
                 if cfg!(target_endian = "little") { self } else { self.swap_bytes() }
@@ -2313,7 +2579,7 @@
 ```
 ", $Feature, "assert_eq!((", stringify!($SelfT), "::max_value() - 2).checked_add(1), ",
 "Some(", stringify!($SelfT), "::max_value() - 1));
-assert_eq!((", stringify!($SelfT), "::max_value() - 2).checked_add(3),None);", $EndFeature, "
+assert_eq!((", stringify!($SelfT), "::max_value() - 2).checked_add(3), None);", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
             #[inline]
@@ -4443,17 +4709,57 @@
 // Conversions T -> T are covered by a blanket impl and therefore excluded
 // Some conversions from and to usize/isize are not implemented due to portability concerns
 macro_rules! impl_from {
-    ($Small: ty, $Large: ty, #[$attr:meta]) => {
+    ($Small: ty, $Large: ty, #[$attr:meta], $doc: expr) => {
         #[$attr]
+        #[doc = $doc]
         impl From<$Small> for $Large {
             #[inline]
             fn from(small: $Small) -> $Large {
                 small as $Large
             }
         }
+    };
+    ($Small: ty, $Large: ty, #[$attr:meta]) => {
+        impl_from!($Small,
+                   $Large,
+                   #[$attr],
+                   concat!("Converts `",
+                           stringify!($Small),
+                           "` to `",
+                           stringify!($Large),
+                           "` losslessly."));
     }
 }
 
+macro_rules! impl_from_bool {
+    ($target: ty, #[$attr:meta]) => {
+        impl_from!(bool, $target, #[$attr], concat!("Converts a `bool` to a `",
+            stringify!($target), "`. The resulting value is `0` for `false` and `1` for `true`
+values.
+
+# Examples
+
+```
+assert_eq!(", stringify!($target), "::from(true), 1);
+assert_eq!(", stringify!($target), "::from(false), 0);
+```"));
+    };
+}
+
+// Bool -> Any
+impl_from_bool! { u8, #[stable(feature = "from_bool", since = "1.28.0")] }
+impl_from_bool! { u16, #[stable(feature = "from_bool", since = "1.28.0")] }
+impl_from_bool! { u32, #[stable(feature = "from_bool", since = "1.28.0")] }
+impl_from_bool! { u64, #[stable(feature = "from_bool", since = "1.28.0")] }
+impl_from_bool! { u128, #[stable(feature = "from_bool", since = "1.28.0")] }
+impl_from_bool! { usize, #[stable(feature = "from_bool", since = "1.28.0")] }
+impl_from_bool! { i8, #[stable(feature = "from_bool", since = "1.28.0")] }
+impl_from_bool! { i16, #[stable(feature = "from_bool", since = "1.28.0")] }
+impl_from_bool! { i32, #[stable(feature = "from_bool", since = "1.28.0")] }
+impl_from_bool! { i64, #[stable(feature = "from_bool", since = "1.28.0")] }
+impl_from_bool! { i128, #[stable(feature = "from_bool", since = "1.28.0")] }
+impl_from_bool! { isize, #[stable(feature = "from_bool", since = "1.28.0")] }
+
 // Unsigned -> Unsigned
 impl_from! { u8, u16, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
 impl_from! { u8, u32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
diff --git a/src/libcore/panic.rs b/src/libcore/panic.rs
index 27ec4aa..37ae053 100644
--- a/src/libcore/panic.rs
+++ b/src/libcore/panic.rs
@@ -35,6 +35,7 @@
 ///
 /// panic!("Normal panic");
 /// ```
+#[cfg_attr(not(stage0), lang = "panic_info")]
 #[stable(feature = "panic_hooks", since = "1.10.0")]
 #[derive(Debug)]
 pub struct PanicInfo<'a> {
@@ -53,7 +54,8 @@
     pub fn internal_constructor(message: Option<&'a fmt::Arguments<'a>>,
                                 location: Location<'a>)
                                 -> Self {
-        PanicInfo { payload: &(), location, message }
+        struct NoPayload;
+        PanicInfo { payload: &NoPayload, location, message }
     }
 
     #[doc(hidden)]
@@ -121,7 +123,7 @@
     #[stable(feature = "panic_hooks", since = "1.10.0")]
     pub fn location(&self) -> Option<&Location> {
         // NOTE: If this is changed to sometimes return None,
-        // deal with that case in std::panicking::default_hook.
+        // deal with that case in std::panicking::default_hook and std::panicking::begin_panic_fmt.
         Some(&self.location)
     }
 }
diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs
index 6b3dc75..0d4f8d1 100644
--- a/src/libcore/panicking.rs
+++ b/src/libcore/panicking.rs
@@ -37,6 +37,8 @@
             issue = "0")]
 
 use fmt;
+#[cfg(not(stage0))]
+use panic::{Location, PanicInfo};
 
 #[cold] #[inline(never)] // this is the slow path, always
 #[lang = "panic"]
@@ -59,6 +61,7 @@
                            len, index), file_line_col)
 }
 
+#[cfg(stage0)]
 #[cold] #[inline(never)]
 pub fn panic_fmt(fmt: fmt::Arguments, file_line_col: &(&'static str, u32, u32)) -> ! {
     #[allow(improper_ctypes)]
@@ -70,3 +73,21 @@
     let (file, line, col) = *file_line_col;
     unsafe { panic_impl(fmt, file, line, col) }
 }
+
+#[cfg(not(stage0))]
+#[cold] #[inline(never)]
+pub fn panic_fmt(fmt: fmt::Arguments, file_line_col: &(&'static str, u32, u32)) -> ! {
+    // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
+    #[allow(improper_ctypes)] // PanicInfo contains a trait object which is not FFI safe
+    extern "Rust" {
+        #[lang = "panic_impl"]
+        fn panic_impl(pi: &PanicInfo) -> !;
+    }
+
+    let (file, line, col) = *file_line_col;
+    let pi = PanicInfo::internal_constructor(
+        Some(&fmt),
+        Location::internal_constructor(file, line, col),
+    );
+    unsafe { panic_impl(&pi) }
+}
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 6c0709c..81a8b3e 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -239,8 +239,9 @@
     }
 }
 
-/// Replaces the value at `dest` with `src`, returning the old
-/// value, without dropping either.
+/// Moves `src` into the pointed `dest`, returning the previous `dest` value.
+///
+/// Neither value is dropped.
 ///
 /// # Safety
 ///
@@ -2921,14 +2922,6 @@
             NonNull::new_unchecked(self.as_ptr() as *mut U)
         }
     }
-
-    /// Cast to an `Opaque` pointer
-    #[unstable(feature = "allocator_api", issue = "32838")]
-    pub fn as_opaque(self) -> NonNull<::alloc::Opaque> {
-        unsafe {
-            NonNull::new_unchecked(self.as_ptr() as _)
-        }
-    }
 }
 
 #[stable(feature = "nonnull", since = "1.25.0")]
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index d52cc8c..6f4c130 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -691,41 +691,6 @@
         Chunks { v: self, chunk_size: chunk_size }
     }
 
-    /// Returns an iterator over `chunk_size` elements of the slice at a
-    /// time. The chunks are slices and do not overlap. If `chunk_size` does
-    /// not divide the length of the slice, then the last up to `chunk_size-1`
-    /// elements will be omitted.
-    ///
-    /// Due to each chunk having exactly `chunk_size` elements, the compiler
-    /// can often optimize the resulting code better than in the case of
-    /// [`chunks`].
-    ///
-    /// # Panics
-    ///
-    /// Panics if `chunk_size` is 0.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(exact_chunks)]
-    ///
-    /// let slice = ['l', 'o', 'r', 'e', 'm'];
-    /// let mut iter = slice.exact_chunks(2);
-    /// assert_eq!(iter.next().unwrap(), &['l', 'o']);
-    /// assert_eq!(iter.next().unwrap(), &['r', 'e']);
-    /// assert!(iter.next().is_none());
-    /// ```
-    ///
-    /// [`chunks`]: #method.chunks
-    #[unstable(feature = "exact_chunks", issue = "47115")]
-    #[inline]
-    pub fn exact_chunks(&self, chunk_size: usize) -> ExactChunks<T> {
-        assert!(chunk_size != 0);
-        let rem = self.len() % chunk_size;
-        let len = self.len() - rem;
-        ExactChunks { v: &self[..len], chunk_size: chunk_size}
-    }
-
     /// Returns an iterator over `chunk_size` elements of the slice at a time.
     /// The chunks are mutable slices, and do not overlap. If `chunk_size` does
     /// not divide the length of the slice, then the last chunk will not
@@ -761,6 +726,41 @@
         ChunksMut { v: self, chunk_size: chunk_size }
     }
 
+    /// Returns an iterator over `chunk_size` elements of the slice at a
+    /// time. The chunks are slices and do not overlap. If `chunk_size` does
+    /// not divide the length of the slice, then the last up to `chunk_size-1`
+    /// elements will be omitted.
+    ///
+    /// Due to each chunk having exactly `chunk_size` elements, the compiler
+    /// can often optimize the resulting code better than in the case of
+    /// [`chunks`].
+    ///
+    /// # Panics
+    ///
+    /// Panics if `chunk_size` is 0.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(exact_chunks)]
+    ///
+    /// let slice = ['l', 'o', 'r', 'e', 'm'];
+    /// let mut iter = slice.exact_chunks(2);
+    /// assert_eq!(iter.next().unwrap(), &['l', 'o']);
+    /// assert_eq!(iter.next().unwrap(), &['r', 'e']);
+    /// assert!(iter.next().is_none());
+    /// ```
+    ///
+    /// [`chunks`]: #method.chunks
+    #[unstable(feature = "exact_chunks", issue = "47115")]
+    #[inline]
+    pub fn exact_chunks(&self, chunk_size: usize) -> ExactChunks<T> {
+        assert!(chunk_size != 0);
+        let rem = self.len() % chunk_size;
+        let len = self.len() - rem;
+        ExactChunks { v: &self[..len], chunk_size: chunk_size}
+    }
+
     /// Returns an iterator over `chunk_size` elements of the slice at a time.
     /// The chunks are mutable slices, and do not overlap. If `chunk_size` does
     /// not divide the length of the slice, then the last up to `chunk_size-1`
@@ -1977,35 +1977,63 @@
     panic!("attempted to index slice up to maximum usize");
 }
 
+mod private_slice_index {
+    use super::ops;
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
+    pub trait Sealed {}
+
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
+    impl Sealed for usize {}
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
+    impl Sealed for ops::Range<usize> {}
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
+    impl Sealed for ops::RangeTo<usize> {}
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
+    impl Sealed for ops::RangeFrom<usize> {}
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
+    impl Sealed for ops::RangeFull {}
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
+    impl Sealed for ops::RangeInclusive<usize> {}
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
+    impl Sealed for ops::RangeToInclusive<usize> {}
+}
+
 /// A helper trait used for indexing operations.
-#[unstable(feature = "slice_get_slice", issue = "35729")]
+#[stable(feature = "slice_get_slice", since = "1.28.0")]
 #[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"]
-pub trait SliceIndex<T: ?Sized> {
+pub trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
     /// The output type returned by methods.
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
     type Output: ?Sized;
 
     /// Returns a shared reference to the output at this location, if in
     /// bounds.
+    #[unstable(feature = "slice_index_methods", issue = "0")]
     fn get(self, slice: &T) -> Option<&Self::Output>;
 
     /// Returns a mutable reference to the output at this location, if in
     /// bounds.
+    #[unstable(feature = "slice_index_methods", issue = "0")]
     fn get_mut(self, slice: &mut T) -> Option<&mut Self::Output>;
 
     /// Returns a shared reference to the output at this location, without
     /// performing any bounds checking.
+    #[unstable(feature = "slice_index_methods", issue = "0")]
     unsafe fn get_unchecked(self, slice: &T) -> &Self::Output;
 
     /// Returns a mutable reference to the output at this location, without
     /// performing any bounds checking.
+    #[unstable(feature = "slice_index_methods", issue = "0")]
     unsafe fn get_unchecked_mut(self, slice: &mut T) -> &mut Self::Output;
 
     /// Returns a shared reference to the output at this location, panicking
     /// if out of bounds.
+    #[unstable(feature = "slice_index_methods", issue = "0")]
     fn index(self, slice: &T) -> &Self::Output;
 
     /// Returns a mutable reference to the output at this location, panicking
     /// if out of bounds.
+    #[unstable(feature = "slice_index_methods", issue = "0")]
     fn index_mut(self, slice: &mut T) -> &mut Self::Output;
 }
 
@@ -2513,6 +2541,12 @@
                 accum
             }
         }
+
+        #[stable(feature = "fused", since = "1.26.0")]
+        impl<'a, T> FusedIterator for $name<'a, T> {}
+
+        #[unstable(feature = "trusted_len", issue = "37572")]
+        unsafe impl<'a, T> TrustedLen for $name<'a, T> {}
     }
 }
 
@@ -2639,12 +2673,6 @@
     }
 }
 
-#[stable(feature = "fused", since = "1.26.0")]
-impl<'a, T> FusedIterator for Iter<'a, T> {}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<'a, T> TrustedLen for Iter<'a, T> {}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> Clone for Iter<'a, T> {
     fn clone(&self) -> Iter<'a, T> { Iter { ptr: self.ptr, end: self.end, _marker: self._marker } }
@@ -2706,9 +2734,7 @@
     /// View the underlying data as a subslice of the original data.
     ///
     /// To avoid creating `&mut` references that alias, this is forced
-    /// to consume the iterator. Consider using the `Slice` and
-    /// `SliceMut` implementations for obtaining slices with more
-    /// restricted lifetimes that do not consume the iterator.
+    /// to consume the iterator.
     ///
     /// # Examples
     ///
@@ -2767,13 +2793,6 @@
     }
 }
 
-#[stable(feature = "fused", since = "1.26.0")]
-impl<'a, T> FusedIterator for IterMut<'a, T> {}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<'a, T> TrustedLen for IterMut<'a, T> {}
-
-
 // Return the number of elements of `T` from `start` to `end`.
 // Return the arithmetic difference if `T` is zero size.
 #[inline(always)]
@@ -3371,6 +3390,9 @@
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> ExactSizeIterator for Windows<'a, T> {}
 
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<'a, T> TrustedLen for Windows<'a, T> {}
+
 #[stable(feature = "fused", since = "1.26.0")]
 impl<'a, T> FusedIterator for Windows<'a, T> {}
 
@@ -3490,6 +3512,9 @@
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> ExactSizeIterator for Chunks<'a, T> {}
 
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<'a, T> TrustedLen for Chunks<'a, T> {}
+
 #[stable(feature = "fused", since = "1.26.0")]
 impl<'a, T> FusedIterator for Chunks<'a, T> {}
 
@@ -3606,6 +3631,9 @@
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> ExactSizeIterator for ChunksMut<'a, T> {}
 
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<'a, T> TrustedLen for ChunksMut<'a, T> {}
+
 #[stable(feature = "fused", since = "1.26.0")]
 impl<'a, T> FusedIterator for ChunksMut<'a, T> {}
 
@@ -3716,6 +3744,9 @@
     }
 }
 
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<'a, T> TrustedLen for ExactChunks<'a, T> {}
+
 #[unstable(feature = "exact_chunks", issue = "47115")]
 impl<'a, T> FusedIterator for ExactChunks<'a, T> {}
 
@@ -3813,6 +3844,9 @@
     }
 }
 
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<'a, T> TrustedLen for ExactChunksMut<'a, T> {}
+
 #[unstable(feature = "exact_chunks", issue = "47115")]
 impl<'a, T> FusedIterator for ExactChunksMut<'a, T> {}
 
@@ -3839,9 +3873,11 @@
 /// valid for `len` elements, nor whether the lifetime inferred is a suitable
 /// lifetime for the returned slice.
 ///
-/// `p` must be non-null and aligned, even for zero-length slices, as is
-/// required for all references. However, for zero-length slices, `p` can be
-/// a bogus non-dereferencable pointer such as [`NonNull::dangling()`].
+/// `data` must be non-null and aligned, even for zero-length slices. One
+/// reason for this is that enum layout optimizations may rely on references
+/// (including slices of any length) being aligned and non-null to distinguish
+/// them from other data. You can obtain a pointer that is usable as `data`
+/// for zero-length slices using [`NonNull::dangling()`].
 ///
 /// # Caveat
 ///
@@ -3876,8 +3912,8 @@
 ///
 /// This function is unsafe for the same reasons as `from_raw_parts`, as well
 /// as not being able to provide a non-aliasing guarantee of the returned
-/// mutable slice. `p` must be non-null and aligned even for zero-length slices as with
-/// `from_raw_parts`.
+/// mutable slice. `data` must be non-null and aligned even for zero-length
+/// slices as with `from_raw_parts`.
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 3169893..5e1a9c25 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -3875,6 +3875,12 @@
     fn default() -> &'a str { "" }
 }
 
+#[stable(feature = "default_mut_str", since = "1.28.0")]
+impl<'a> Default for &'a mut str {
+    /// Creates an empty mutable str
+    fn default() -> &'a mut str { unsafe { from_utf8_unchecked_mut(&mut []) } }
+}
+
 /// An iterator over the non-whitespace substrings of a string,
 /// separated by any amount of whitespace.
 ///
diff --git a/src/libcore/task.rs b/src/libcore/task.rs
new file mode 100644
index 0000000..1a6018f
--- /dev/null
+++ b/src/libcore/task.rs
@@ -0,0 +1,569 @@
+// Copyright 2018 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.
+
+#![unstable(feature = "futures_api",
+            reason = "futures in libcore are unstable",
+            issue = "50547")]
+
+//! Types and Traits for working with asynchronous tasks.
+
+use fmt;
+use ptr::NonNull;
+use future::Future;
+use mem::PinMut;
+
+/// Indicates whether a value is available or if the current task has been
+/// scheduled to receive a wakeup instead.
+#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
+pub enum Poll<T> {
+    /// Represents that a value is immediately ready.
+    Ready(T),
+
+    /// Represents that a value is not ready yet.
+    ///
+    /// When a function returns `Pending`, the function *must* also
+    /// ensure that the current task is scheduled to be awoken when
+    /// progress can be made.
+    Pending,
+}
+
+impl<T> Poll<T> {
+    /// Change the ready value of this `Poll` with the closure provided
+    pub fn map<U, F>(self, f: F) -> Poll<U>
+        where F: FnOnce(T) -> U
+    {
+        match self {
+            Poll::Ready(t) => Poll::Ready(f(t)),
+            Poll::Pending => Poll::Pending,
+        }
+    }
+
+    /// Returns whether this is `Poll::Ready`
+    pub fn is_ready(&self) -> bool {
+        match *self {
+            Poll::Ready(_) => true,
+            Poll::Pending => false,
+        }
+    }
+
+    /// Returns whether this is `Poll::Pending`
+    pub fn is_pending(&self) -> bool {
+        !self.is_ready()
+    }
+}
+
+impl<T, E> Poll<Result<T, E>> {
+    /// Change the success value of this `Poll` with the closure provided
+    pub fn map_ok<U, F>(self, f: F) -> Poll<Result<U, E>>
+        where F: FnOnce(T) -> U
+    {
+        match self {
+            Poll::Ready(Ok(t)) => Poll::Ready(Ok(f(t))),
+            Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
+            Poll::Pending => Poll::Pending,
+        }
+    }
+
+    /// Change the error value of this `Poll` with the closure provided
+    pub fn map_err<U, F>(self, f: F) -> Poll<Result<T, U>>
+        where F: FnOnce(E) -> U
+    {
+        match self {
+            Poll::Ready(Ok(t)) => Poll::Ready(Ok(t)),
+            Poll::Ready(Err(e)) => Poll::Ready(Err(f(e))),
+            Poll::Pending => Poll::Pending,
+        }
+    }
+}
+
+impl<T> From<T> for Poll<T> {
+    fn from(t: T) -> Poll<T> {
+        Poll::Ready(t)
+    }
+}
+
+/// A `Waker` is a handle for waking up a task by notifying its executor that it
+/// is ready to be run.
+///
+/// This handle contains a trait object pointing to an instance of the `UnsafeWake`
+/// trait, allowing notifications to get routed through it.
+#[repr(transparent)]
+pub struct Waker {
+    inner: NonNull<UnsafeWake>,
+}
+
+unsafe impl Send for Waker {}
+unsafe impl Sync for Waker {}
+
+impl Waker {
+    /// Constructs a new `Waker` directly.
+    ///
+    /// Note that most code will not need to call this. Implementers of the
+    /// `UnsafeWake` trait will typically provide a wrapper that calls this
+    /// but you otherwise shouldn't call it directly.
+    ///
+    /// If you're working with the standard library then it's recommended to
+    /// use the `Waker::from` function instead which works with the safe
+    /// `Arc` type and the safe `Wake` trait.
+    #[inline]
+    pub unsafe fn new(inner: NonNull<UnsafeWake>) -> Self {
+        Waker { inner: inner }
+    }
+
+    /// Wake up the task associated with this `Waker`.
+    #[inline]
+    pub fn wake(&self) {
+        unsafe { self.inner.as_ref().wake() }
+    }
+
+    /// Returns whether or not this `Waker` and `other` awaken the same task.
+    ///
+    /// This function works on a best-effort basis, and may return false even
+    /// when the `Waker`s would awaken the same task. However, if this function
+    /// returns true, it is guaranteed that the `Waker`s will awaken the same
+    /// task.
+    ///
+    /// This function is primarily used for optimization purposes.
+    #[inline]
+    pub fn will_wake(&self, other: &Waker) -> bool {
+        self.inner == other.inner
+    }
+}
+
+impl Clone for Waker {
+    #[inline]
+    fn clone(&self) -> Self {
+        unsafe {
+            self.inner.as_ref().clone_raw()
+        }
+    }
+}
+
+impl fmt::Debug for Waker {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("Waker")
+            .finish()
+    }
+}
+
+impl Drop for Waker {
+    #[inline]
+    fn drop(&mut self) {
+        unsafe {
+            self.inner.as_ref().drop_raw()
+        }
+    }
+}
+
+/// A `LocalWaker` is a handle for waking up a task by notifying its executor that it
+/// is ready to be run.
+///
+/// This is similar to the `Waker` type, but cannot be sent across threads.
+/// Task executors can use this type to implement more optimized singlethreaded wakeup
+/// behavior.
+#[repr(transparent)]
+pub struct LocalWaker {
+    inner: NonNull<UnsafeWake>,
+}
+
+impl !Send for LocalWaker {}
+impl !Sync for LocalWaker {}
+
+impl LocalWaker {
+    /// Constructs a new `LocalWaker` directly.
+    ///
+    /// Note that most code will not need to call this. Implementers of the
+    /// `UnsafeWake` trait will typically provide a wrapper that calls this
+    /// but you otherwise shouldn't call it directly.
+    ///
+    /// If you're working with the standard library then it's recommended to
+    /// use the `LocalWaker::from` function instead which works with the safe
+    /// `Rc` type and the safe `LocalWake` trait.
+    ///
+    /// For this function to be used safely, it must be sound to call `inner.wake_local()`
+    /// on the current thread.
+    #[inline]
+    pub unsafe fn new(inner: NonNull<UnsafeWake>) -> Self {
+        LocalWaker { inner: inner }
+    }
+
+    /// Wake up the task associated with this `LocalWaker`.
+    #[inline]
+    pub fn wake(&self) {
+        unsafe { self.inner.as_ref().wake_local() }
+    }
+
+    /// Returns whether or not this `LocalWaker` and `other` `LocalWaker` awaken the same task.
+    ///
+    /// This function works on a best-effort basis, and may return false even
+    /// when the `LocalWaker`s would awaken the same task. However, if this function
+    /// returns true, it is guaranteed that the `LocalWaker`s will awaken the same
+    /// task.
+    ///
+    /// This function is primarily used for optimization purposes.
+    #[inline]
+    pub fn will_wake(&self, other: &LocalWaker) -> bool {
+        self.inner == other.inner
+    }
+
+    /// Returns whether or not this `LocalWaker` and `other` `Waker` awaken the same task.
+    ///
+    /// This function works on a best-effort basis, and may return false even
+    /// when the `Waker`s would awaken the same task. However, if this function
+    /// returns true, it is guaranteed that the `LocalWaker`s will awaken the same
+    /// task.
+    ///
+    /// This function is primarily used for optimization purposes.
+    #[inline]
+    pub fn will_wake_nonlocal(&self, other: &Waker) -> bool {
+        self.inner == other.inner
+    }
+}
+
+impl From<LocalWaker> for Waker {
+    #[inline]
+    fn from(local_waker: LocalWaker) -> Self {
+        Waker { inner: local_waker.inner }
+    }
+}
+
+impl Clone for LocalWaker {
+    #[inline]
+    fn clone(&self) -> Self {
+        unsafe {
+            LocalWaker { inner: self.inner.as_ref().clone_raw().inner }
+        }
+    }
+}
+
+impl fmt::Debug for LocalWaker {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("Waker")
+            .finish()
+    }
+}
+
+impl Drop for LocalWaker {
+    #[inline]
+    fn drop(&mut self) {
+        unsafe {
+            self.inner.as_ref().drop_raw()
+        }
+    }
+}
+
+/// An unsafe trait for implementing custom memory management for a `Waker` or `LocalWaker`.
+///
+/// A `Waker` conceptually is a cloneable trait object for `Wake`, and is
+/// most often essentially just `Arc<dyn Wake>`. However, in some contexts
+/// (particularly `no_std`), it's desirable to avoid `Arc` in favor of some
+/// custom memory management strategy. This trait is designed to allow for such
+/// customization.
+///
+/// When using `std`, a default implementation of the `UnsafeWake` trait is provided for
+/// `Arc<T>` where `T: Wake` and `Rc<T>` where `T: LocalWake`.
+///
+/// Although the methods on `UnsafeWake` take pointers rather than references,
+pub unsafe trait UnsafeWake: Send + Sync {
+    /// Creates a clone of this `UnsafeWake` and stores it behind a `Waker`.
+    ///
+    /// This function will create a new uniquely owned handle that under the
+    /// hood references the same notification instance. In other words calls
+    /// to `wake` on the returned handle should be equivalent to calls to
+    /// `wake` on this handle.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe to call because it's asserting the `UnsafeWake`
+    /// value is in a consistent state, i.e. hasn't been dropped.
+    unsafe fn clone_raw(&self) -> Waker;
+
+    /// Drops this instance of `UnsafeWake`, deallocating resources
+    /// associated with it.
+    ///
+    /// FIXME(cramertj)
+    /// This method is intended to have a signature such as:
+    ///
+    /// ```ignore (not-a-doctest)
+    /// fn drop_raw(self: *mut Self);
+    /// ```
+    ///
+    /// Unfortunately in Rust today that signature is not object safe.
+    /// Nevertheless it's recommended to implement this function *as if* that
+    /// were its signature. As such it is not safe to call on an invalid
+    /// pointer, nor is the validity of the pointer guaranteed after this
+    /// function returns.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe to call because it's asserting the `UnsafeWake`
+    /// value is in a consistent state, i.e. hasn't been dropped.
+    unsafe fn drop_raw(&self);
+
+    /// Indicates that the associated task is ready to make progress and should
+    /// be `poll`ed.
+    ///
+    /// Executors generally maintain a queue of "ready" tasks; `wake` should place
+    /// the associated task onto this queue.
+    ///
+    /// # Panics
+    ///
+    /// Implementations should avoid panicking, but clients should also be prepared
+    /// for panics.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe to call because it's asserting the `UnsafeWake`
+    /// value is in a consistent state, i.e. hasn't been dropped.
+    unsafe fn wake(&self);
+
+    /// Indicates that the associated task is ready to make progress and should
+    /// be `poll`ed. This function is the same as `wake`, but can only be called
+    /// from the thread that this `UnsafeWake` is "local" to. This allows for
+    /// implementors to provide specialized wakeup behavior specific to the current
+    /// thread. This function is called by `LocalWaker::wake`.
+    ///
+    /// Executors generally maintain a queue of "ready" tasks; `wake_local` should place
+    /// the associated task onto this queue.
+    ///
+    /// # Panics
+    ///
+    /// Implementations should avoid panicking, but clients should also be prepared
+    /// for panics.
+    ///
+    /// # Unsafety
+    ///
+    /// This function is unsafe to call because it's asserting the `UnsafeWake`
+    /// value is in a consistent state, i.e. hasn't been dropped, and that the
+    /// `UnsafeWake` hasn't moved from the thread on which it was created.
+    unsafe fn wake_local(&self) {
+        self.wake()
+    }
+}
+
+/// Information about the currently-running task.
+///
+/// Contexts are always tied to the stack, since they are set up specifically
+/// when performing a single `poll` step on a task.
+pub struct Context<'a> {
+    local_waker: &'a LocalWaker,
+    executor: &'a mut Executor,
+}
+
+impl<'a> fmt::Debug for Context<'a> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("Context")
+            .finish()
+    }
+}
+
+impl<'a> Context<'a> {
+    /// Create a new task `Context` with the provided `local_waker`, `waker`, and `executor`.
+    #[inline]
+    pub fn new(local_waker: &'a LocalWaker, executor: &'a mut Executor) -> Context<'a> {
+        Context {
+            local_waker,
+            executor,
+        }
+    }
+
+    /// Get the `LocalWaker` associated with the current task.
+    #[inline]
+    pub fn local_waker(&self) -> &'a LocalWaker {
+        self.local_waker
+    }
+
+    /// Get the `Waker` associated with the current task.
+    #[inline]
+    pub fn waker(&self) -> &'a Waker {
+        unsafe { &*(self.local_waker as *const LocalWaker as *const Waker) }
+    }
+
+    /// Get the default executor associated with this task.
+    ///
+    /// This method is useful primarily if you want to explicitly handle
+    /// spawn failures.
+    #[inline]
+    pub fn executor(&mut self) -> &mut Executor {
+        self.executor
+    }
+
+    /// Produce a context like the current one, but using the given waker instead.
+    ///
+    /// This advanced method is primarily used when building "internal
+    /// schedulers" within a task, where you want to provide some customized
+    /// wakeup logic.
+    #[inline]
+    pub fn with_waker<'b>(&'b mut self, local_waker: &'b LocalWaker) -> Context<'b> {
+        Context {
+            local_waker,
+            executor: self.executor,
+        }
+    }
+
+    /// Produce a context like the current one, but using the given executor
+    /// instead.
+    ///
+    /// This advanced method is primarily used when building "internal
+    /// schedulers" within a task.
+    #[inline]
+    pub fn with_executor<'b, E>(&'b mut self, executor: &'b mut E) -> Context<'b>
+        where E: Executor
+    {
+        Context {
+            local_waker: self.local_waker,
+            executor: executor,
+        }
+    }
+}
+
+/// A task executor.
+///
+/// A *task* is a `()`-producing async value that runs at the top level, and will
+/// be `poll`ed until completion. It's also the unit at which wake-up
+/// notifications occur. Executors, such as thread pools, allow tasks to be
+/// spawned and are responsible for putting tasks onto ready queues when
+/// they are woken up, and polling them when they are ready.
+pub trait Executor {
+    /// Spawn the given task, polling it until completion.
+    ///
+    /// # Errors
+    ///
+    /// The executor may be unable to spawn tasks, either because it has
+    /// been shut down or is resource-constrained.
+    fn spawn_obj(&mut self, task: TaskObj) -> Result<(), SpawnObjError>;
+
+    /// Determine whether the executor is able to spawn new tasks.
+    ///
+    /// # Returns
+    ///
+    /// An `Ok` return means the executor is *likely* (but not guaranteed)
+    /// to accept a subsequent spawn attempt. Likewise, an `Err` return
+    /// means that `spawn` is likely, but not guaranteed, to yield an error.
+    #[inline]
+    fn status(&self) -> Result<(), SpawnErrorKind> {
+        Ok(())
+    }
+}
+
+/// A custom trait object for polling tasks, roughly akin to
+/// `Box<Future<Output = ()> + Send>`.
+pub struct TaskObj {
+    ptr: *mut (),
+    poll_fn: unsafe fn(*mut (), &mut Context) -> Poll<()>,
+    drop_fn: unsafe fn(*mut ()),
+}
+
+impl fmt::Debug for TaskObj {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("TaskObj")
+            .finish()
+    }
+}
+
+unsafe impl Send for TaskObj {}
+
+/// A custom implementation of a task trait object for `TaskObj`, providing
+/// a hand-rolled vtable.
+///
+/// This custom representation is typically used only in `no_std` contexts,
+/// where the default `Box`-based implementation is not available.
+///
+/// The implementor must guarantee that it is safe to call `poll` repeatedly (in
+/// a non-concurrent fashion) with the result of `into_raw` until `drop` is
+/// called.
+pub unsafe trait UnsafeTask: Send + 'static {
+    /// Convert a owned instance into a (conceptually owned) void pointer.
+    fn into_raw(self) -> *mut ();
+
+    /// Poll the task represented by the given void pointer.
+    ///
+    /// # Safety
+    ///
+    /// The trait implementor must guarantee that it is safe to repeatedly call
+    /// `poll` with the result of `into_raw` until `drop` is called; such calls
+    /// are not, however, allowed to race with each other or with calls to `drop`.
+    unsafe fn poll(task: *mut (), cx: &mut Context) -> Poll<()>;
+
+    /// Drops the task represented by the given void pointer.
+    ///
+    /// # Safety
+    ///
+    /// The trait implementor must guarantee that it is safe to call this
+    /// function once per `into_raw` invocation; that call cannot race with
+    /// other calls to `drop` or `poll`.
+    unsafe fn drop(task: *mut ());
+}
+
+impl TaskObj {
+    /// Create a `TaskObj` from a custom trait object representation.
+    #[inline]
+    pub fn new<T: UnsafeTask>(t: T) -> TaskObj {
+        TaskObj {
+            ptr: t.into_raw(),
+            poll_fn: T::poll,
+            drop_fn: T::drop,
+        }
+    }
+}
+
+impl Future for TaskObj {
+    type Output = ();
+
+    #[inline]
+    fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<()> {
+        unsafe {
+            (self.poll_fn)(self.ptr, cx)
+        }
+    }
+}
+
+impl Drop for TaskObj {
+    fn drop(&mut self) {
+        unsafe {
+            (self.drop_fn)(self.ptr)
+        }
+    }
+}
+
+/// Provides the reason that an executor was unable to spawn.
+pub struct SpawnErrorKind {
+    _hidden: (),
+}
+
+impl fmt::Debug for SpawnErrorKind {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_tuple("SpawnErrorKind")
+            .field(&"shutdown")
+            .finish()
+    }
+}
+
+impl SpawnErrorKind {
+    /// Spawning is failing because the executor has been shut down.
+    pub fn shutdown() -> SpawnErrorKind {
+        SpawnErrorKind { _hidden: () }
+    }
+
+    /// Check whether this error is the `shutdown` error.
+    pub fn is_shutdown(&self) -> bool {
+        true
+    }
+}
+
+/// The result of a failed spawn
+#[derive(Debug)]
+pub struct SpawnObjError {
+    /// The kind of error
+    pub kind: SpawnErrorKind,
+
+    /// The task for which spawning was attempted
+    pub task: TaskObj,
+}
diff --git a/src/libcore/tests/cell.rs b/src/libcore/tests/cell.rs
index 962fb2f..4b7243b 100644
--- a/src/libcore/tests/cell.rs
+++ b/src/libcore/tests/cell.rs
@@ -166,6 +166,64 @@
 }
 
 #[test]
+fn ref_map_split_updates_flag() {
+    let x = RefCell::new([1, 2]);
+    {
+        let b1 = x.borrow();
+        assert!(x.try_borrow().is_ok());
+        assert!(x.try_borrow_mut().is_err());
+        {
+            let (_b2, _b3) = Ref::map_split(b1, |slc| slc.split_at(1));
+            assert!(x.try_borrow().is_ok());
+            assert!(x.try_borrow_mut().is_err());
+        }
+        assert!(x.try_borrow().is_ok());
+        assert!(x.try_borrow_mut().is_ok());
+    }
+    assert!(x.try_borrow().is_ok());
+    assert!(x.try_borrow_mut().is_ok());
+
+    {
+        let b1 = x.borrow_mut();
+        assert!(x.try_borrow().is_err());
+        assert!(x.try_borrow_mut().is_err());
+        {
+            let (_b2, _b3) = RefMut::map_split(b1, |slc| slc.split_at_mut(1));
+            assert!(x.try_borrow().is_err());
+            assert!(x.try_borrow_mut().is_err());
+            drop(_b2);
+            assert!(x.try_borrow().is_err());
+            assert!(x.try_borrow_mut().is_err());
+        }
+        assert!(x.try_borrow().is_ok());
+        assert!(x.try_borrow_mut().is_ok());
+    }
+    assert!(x.try_borrow().is_ok());
+    assert!(x.try_borrow_mut().is_ok());
+}
+
+#[test]
+fn ref_map_split() {
+    let x = RefCell::new([1, 2]);
+    let (b1, b2) = Ref::map_split(x.borrow(), |slc| slc.split_at(1));
+    assert_eq!(*b1, [1]);
+    assert_eq!(*b2, [2]);
+}
+
+#[test]
+fn ref_mut_map_split() {
+    let x = RefCell::new([1, 2]);
+    {
+        let (mut b1, mut b2) = RefMut::map_split(x.borrow_mut(), |slc| slc.split_at_mut(1));
+        assert_eq!(*b1, [1]);
+        assert_eq!(*b2, [2]);
+        b1[0] = 2;
+        b2[0] = 1;
+    }
+    assert_eq!(*x.borrow(), [2, 1]);
+}
+
+#[test]
 fn ref_map_accessor() {
     struct X(RefCell<(u32, char)>);
     impl X {
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index 2abac0c..9b8d703 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -1723,18 +1723,6 @@
 }
 
 #[test]
-fn test_repeat_with_rev() {
-    let mut curr = 1;
-    let mut pow2 = repeat_with(|| { let tmp = curr; curr *= 2; tmp })
-                    .rev().take(4);
-    assert_eq!(pow2.next(), Some(1));
-    assert_eq!(pow2.next(), Some(2));
-    assert_eq!(pow2.next(), Some(4));
-    assert_eq!(pow2.next(), Some(8));
-    assert_eq!(pow2.next(), None);
-}
-
-#[test]
 fn test_repeat_with_take() {
     let mut it = repeat_with(|| 42).take(3);
     assert_eq!(it.next(), Some(42));
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index 13189d53..87612b7 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -23,12 +23,11 @@
 #![feature(flt2dec)]
 #![feature(fmt_internals)]
 #![feature(hashmap_internals)]
-#![feature(iterator_step_by)]
 #![feature(iterator_flatten)]
-#![feature(iterator_repeat_with)]
 #![feature(pattern)]
 #![feature(range_is_empty)]
 #![feature(raw)]
+#![feature(refcell_map_split)]
 #![feature(refcell_replace_swap)]
 #![feature(slice_patterns)]
 #![feature(slice_rotate)]
diff --git a/src/libcore/tests/num/mod.rs b/src/libcore/tests/num/mod.rs
index f343989..b5e6a01 100644
--- a/src/libcore/tests/num/mod.rs
+++ b/src/libcore/tests/num/mod.rs
@@ -134,6 +134,15 @@
 }
 
 macro_rules! test_impl_from {
+    ($fn_name:ident, bool, $target: ty) => {
+        #[test]
+        fn $fn_name() {
+            let one: $target = 1;
+            let zero: $target = 0;
+            assert_eq!(one, <$target>::from(true));
+            assert_eq!(zero, <$target>::from(false));
+        }
+    };
     ($fn_name: ident, $Small: ty, $Large: ty) => {
         #[test]
         fn $fn_name() {
@@ -173,6 +182,18 @@
 test_impl_from! { test_u16i64, u16, i64 }
 test_impl_from! { test_u32i64, u32, i64 }
 
+// Bool -> Integer
+test_impl_from! { test_boolu8, bool, u8 }
+test_impl_from! { test_boolu16, bool, u16 }
+test_impl_from! { test_boolu32, bool, u32 }
+test_impl_from! { test_boolu64, bool, u64 }
+test_impl_from! { test_boolu128, bool, u128 }
+test_impl_from! { test_booli8, bool, i8 }
+test_impl_from! { test_booli16, bool, i16 }
+test_impl_from! { test_booli32, bool, i32 }
+test_impl_from! { test_booli64, bool, i64 }
+test_impl_from! { test_booli128, bool, i128 }
+
 // Signed -> Float
 test_impl_from! { test_i8f32, i8, f32 }
 test_impl_from! { test_i8f64, i8, f64 }
diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs
index ce41bde..d9927ce 100644
--- a/src/libcore/tests/result.rs
+++ b/src/libcore/tests/result.rs
@@ -220,13 +220,15 @@
     assert_eq!(try_result_none(), None);
 
     fn try_result_ok() -> Result<u8, u8> {
-        let val = Ok(1)?;
+        let result: Result<u8, u8> = Ok(1);
+        let val = result?;
         Ok(val)
     }
     assert_eq!(try_result_ok(), Ok(1));
 
     fn try_result_err() -> Result<u8, u8> {
-        let val = Err(1)?;
+        let result: Result<u8, u8> = Err(1);
+        let val = result?;
         Ok(val)
     }
     assert_eq!(try_result_err(), Err(1));
diff --git a/src/libcore/time.rs b/src/libcore/time.rs
index a1815b5..563eea0 100644
--- a/src/libcore/time.rs
+++ b/src/libcore/time.rs
@@ -268,6 +268,57 @@
     #[inline]
     pub const fn subsec_nanos(&self) -> u32 { self.nanos }
 
+    /// Returns the total number of milliseconds contained by this `Duration`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(duration_as_u128)]
+    /// use std::time::Duration;
+    ///
+    /// let duration = Duration::new(5, 730023852);
+    /// assert_eq!(duration.as_millis(), 5730);
+    /// ```
+    #[unstable(feature = "duration_as_u128", issue = "50202")]
+    #[inline]
+    pub fn as_millis(&self) -> u128 {
+        self.secs as u128 * MILLIS_PER_SEC as u128 + (self.nanos / NANOS_PER_MILLI) as u128
+    }
+
+    /// Returns the total number of microseconds contained by this `Duration`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(duration_as_u128)]
+    /// use std::time::Duration;
+    ///
+    /// let duration = Duration::new(5, 730023852);
+    /// assert_eq!(duration.as_micros(), 5730023);
+    /// ```
+    #[unstable(feature = "duration_as_u128", issue = "50202")]
+    #[inline]
+    pub fn as_micros(&self) -> u128 {
+        self.secs as u128 * MICROS_PER_SEC as u128 + (self.nanos / NANOS_PER_MICRO) as u128
+    }
+
+    /// Returns the total number of nanoseconds contained by this `Duration`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(duration_as_u128)]
+    /// use std::time::Duration;
+    ///
+    /// let duration = Duration::new(5, 730023852);
+    /// assert_eq!(duration.as_nanos(), 5730023852);
+    /// ```
+    #[unstable(feature = "duration_as_u128", issue = "50202")]
+    #[inline]
+    pub fn as_nanos(&self) -> u128 {
+        self.secs as u128 * NANOS_PER_SEC as u128 + self.nanos as u128
+    }
+
     /// Checked `Duration` addition. Computes `self + other`, returning [`None`]
     /// if overflow occurred.
     ///
diff --git a/src/libcore/unicode/printable.rs b/src/libcore/unicode/printable.rs
index 4426c32..519dd17 100644
--- a/src/libcore/unicode/printable.rs
+++ b/src/libcore/unicode/printable.rs
@@ -83,14 +83,14 @@
 const SINGLETONS0U: &'static [(u8, u8)] = &[
     (0x00, 1),
     (0x03, 5),
-    (0x05, 8),
+    (0x05, 6),
     (0x06, 3),
-    (0x07, 4),
+    (0x07, 6),
     (0x08, 8),
-    (0x09, 16),
-    (0x0a, 27),
+    (0x09, 17),
+    (0x0a, 28),
     (0x0b, 25),
-    (0x0c, 22),
+    (0x0c, 20),
     (0x0d, 18),
     (0x0e, 22),
     (0x0f, 4),
@@ -102,18 +102,17 @@
     (0x18, 2),
     (0x19, 3),
     (0x1a, 7),
+    (0x1c, 2),
     (0x1d, 1),
     (0x1f, 22),
     (0x20, 3),
-    (0x2b, 5),
+    (0x2b, 6),
     (0x2c, 2),
     (0x2d, 11),
     (0x2e, 1),
     (0x30, 3),
-    (0x31, 3),
+    (0x31, 2),
     (0x32, 2),
-    (0xa7, 1),
-    (0xa8, 2),
     (0xa9, 2),
     (0xaa, 4),
     (0xab, 8),
@@ -125,19 +124,19 @@
 ];
 const SINGLETONS0L: &'static [u8] = &[
     0xad, 0x78, 0x79, 0x8b, 0x8d, 0xa2, 0x30, 0x57,
-    0x58, 0x60, 0x88, 0x8b, 0x8c, 0x90, 0x1c, 0x1d,
-    0xdd, 0x0e, 0x0f, 0x4b, 0x4c, 0x2e, 0x2f, 0x3f,
+    0x58, 0x8b, 0x8c, 0x90, 0x1c, 0x1d, 0xdd, 0x0e,
+    0x0f, 0x4b, 0x4c, 0xfb, 0xfc, 0x2e, 0x2f, 0x3f,
     0x5c, 0x5d, 0x5f, 0xb5, 0xe2, 0x84, 0x8d, 0x8e,
     0x91, 0x92, 0xa9, 0xb1, 0xba, 0xbb, 0xc5, 0xc6,
-    0xc9, 0xca, 0xde, 0xe4, 0xe5, 0x04, 0x11, 0x12,
-    0x29, 0x31, 0x34, 0x37, 0x3a, 0x3b, 0x3d, 0x49,
-    0x4a, 0x5d, 0x84, 0x8e, 0x92, 0xa9, 0xb1, 0xb4,
-    0xba, 0xbb, 0xc6, 0xca, 0xce, 0xcf, 0xe4, 0xe5,
-    0x00, 0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31,
-    0x34, 0x3a, 0x3b, 0x45, 0x46, 0x49, 0x4a, 0x5e,
-    0x64, 0x65, 0x84, 0x91, 0x9b, 0x9d, 0xc9, 0xce,
-    0xcf, 0x04, 0x0d, 0x11, 0x29, 0x45, 0x49, 0x57,
-    0x64, 0x65, 0x84, 0x8d, 0x91, 0xa9, 0xb4, 0xba,
+    0xc9, 0xca, 0xde, 0xe4, 0xe5, 0xff, 0x00, 0x04,
+    0x11, 0x12, 0x29, 0x31, 0x34, 0x37, 0x3a, 0x3b,
+    0x3d, 0x49, 0x4a, 0x5d, 0x84, 0x8e, 0x92, 0xa9,
+    0xb1, 0xb4, 0xba, 0xbb, 0xc6, 0xca, 0xce, 0xcf,
+    0xe4, 0xe5, 0x00, 0x04, 0x0d, 0x0e, 0x11, 0x12,
+    0x29, 0x31, 0x34, 0x3a, 0x3b, 0x45, 0x46, 0x49,
+    0x4a, 0x5e, 0x64, 0x65, 0x84, 0x91, 0x9b, 0x9d,
+    0xc9, 0xce, 0xcf, 0x0d, 0x11, 0x29, 0x45, 0x49,
+    0x57, 0x64, 0x65, 0x8d, 0x91, 0xa9, 0xb4, 0xba,
     0xbb, 0xc5, 0xc9, 0xdf, 0xe4, 0xe5, 0xf0, 0x04,
     0x0d, 0x11, 0x45, 0x49, 0x64, 0x65, 0x80, 0x81,
     0x84, 0xb2, 0xbc, 0xbe, 0xbf, 0xd5, 0xd7, 0xf0,
@@ -150,18 +149,18 @@
     0x11, 0x16, 0x17, 0x5b, 0x5c, 0xf6, 0xf7, 0xfe,
     0xff, 0x80, 0x0d, 0x6d, 0x71, 0xde, 0xdf, 0x0e,
     0x0f, 0x1f, 0x6e, 0x6f, 0x1c, 0x1d, 0x5f, 0x7d,
-    0x7e, 0xae, 0xaf, 0xfa, 0x16, 0x17, 0x1e, 0x1f,
-    0x46, 0x47, 0x4e, 0x4f, 0x58, 0x5a, 0x5c, 0x5e,
-    0x7e, 0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xdc, 0xf0,
-    0xf1, 0xf5, 0x72, 0x73, 0x8f, 0x74, 0x75, 0x96,
-    0x97, 0xc9, 0x2f, 0x5f, 0x26, 0x2e, 0x2f, 0xa7,
-    0xaf, 0xb7, 0xbf, 0xc7, 0xcf, 0xd7, 0xdf, 0x9a,
-    0x40, 0x97, 0x98, 0x2f, 0x30, 0x8f, 0x1f, 0xff,
-    0xaf, 0xfe, 0xff, 0xce, 0xff, 0x4e, 0x4f, 0x5a,
-    0x5b, 0x07, 0x08, 0x0f, 0x10, 0x27, 0x2f, 0xee,
-    0xef, 0x6e, 0x6f, 0x37, 0x3d, 0x3f, 0x42, 0x45,
-    0x90, 0x91, 0xfe, 0xff, 0x53, 0x67, 0x75, 0xc8,
-    0xc9, 0xd0, 0xd1, 0xd8, 0xd9, 0xe7, 0xfe, 0xff,
+    0x7e, 0xae, 0xaf, 0xbb, 0xbc, 0xfa, 0x16, 0x17,
+    0x1e, 0x1f, 0x46, 0x47, 0x4e, 0x4f, 0x58, 0x5a,
+    0x5c, 0x5e, 0x7e, 0x7f, 0xb5, 0xc5, 0xd4, 0xd5,
+    0xdc, 0xf0, 0xf1, 0xf5, 0x72, 0x73, 0x8f, 0x74,
+    0x75, 0x96, 0x97, 0xc9, 0xff, 0x2f, 0x5f, 0x26,
+    0x2e, 0x2f, 0xa7, 0xaf, 0xb7, 0xbf, 0xc7, 0xcf,
+    0xd7, 0xdf, 0x9a, 0x40, 0x97, 0x98, 0x30, 0x8f,
+    0x1f, 0xff, 0xce, 0xff, 0x4e, 0x4f, 0x5a, 0x5b,
+    0x07, 0x08, 0x0f, 0x10, 0x27, 0x2f, 0xee, 0xef,
+    0x6e, 0x6f, 0x37, 0x3d, 0x3f, 0x42, 0x45, 0x90,
+    0x91, 0xfe, 0xff, 0x53, 0x67, 0x75, 0xc8, 0xc9,
+    0xd0, 0xd1, 0xd8, 0xd9, 0xe7, 0xfe, 0xff,
 ];
 const SINGLETONS1U: &'static [(u8, u8)] = &[
     (0x00, 6),
@@ -170,17 +169,18 @@
     (0x04, 2),
     (0x08, 8),
     (0x09, 2),
-    (0x0a, 3),
+    (0x0a, 5),
     (0x0b, 2),
     (0x10, 1),
     (0x11, 4),
     (0x12, 5),
-    (0x13, 18),
+    (0x13, 17),
     (0x14, 2),
     (0x15, 2),
-    (0x1a, 3),
+    (0x17, 2),
+    (0x1a, 2),
     (0x1c, 5),
-    (0x1d, 4),
+    (0x1d, 8),
     (0x24, 1),
     (0x6a, 3),
     (0x6b, 2),
@@ -195,51 +195,49 @@
     (0xe8, 2),
     (0xee, 32),
     (0xf0, 4),
-    (0xf1, 1),
-    (0xf9, 1),
+    (0xf9, 4),
 ];
 const SINGLETONS1L: &'static [u8] = &[
     0x0c, 0x27, 0x3b, 0x3e, 0x4e, 0x4f, 0x8f, 0x9e,
     0x9e, 0x9f, 0x06, 0x07, 0x09, 0x36, 0x3d, 0x3e,
-    0x56, 0xf3, 0xd0, 0xd1, 0x04, 0x14, 0x18, 0x56,
-    0x57, 0xbd, 0x35, 0xce, 0xcf, 0xe0, 0x12, 0x87,
-    0x89, 0x8e, 0x9e, 0x04, 0x0d, 0x0e, 0x11, 0x12,
-    0x29, 0x31, 0x34, 0x3a, 0x3b, 0x45, 0x46, 0x49,
-    0x4a, 0x4e, 0x4f, 0x64, 0x65, 0x5a, 0x5c, 0xb6,
-    0xb7, 0x84, 0x85, 0x9d, 0x09, 0x37, 0x90, 0x91,
-    0xa8, 0x07, 0x0a, 0x3b, 0x3e, 0x6f, 0x5f, 0xee,
-    0xef, 0x5a, 0x62, 0x9a, 0x9b, 0x27, 0x28, 0x55,
-    0x9d, 0xa0, 0xa1, 0xa3, 0xa4, 0xa7, 0xa8, 0xad,
-    0xba, 0xbc, 0xc4, 0x06, 0x0b, 0x0c, 0x15, 0x1d,
-    0x3a, 0x3f, 0x45, 0x51, 0xa6, 0xa7, 0xcc, 0xcd,
-    0xa0, 0x07, 0x19, 0x1a, 0x22, 0x25, 0xc5, 0xc6,
-    0x04, 0x20, 0x23, 0x25, 0x26, 0x28, 0x33, 0x38,
-    0x3a, 0x48, 0x4a, 0x4c, 0x50, 0x53, 0x55, 0x56,
-    0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x63, 0x65, 0x66,
-    0x6b, 0x73, 0x78, 0x7d, 0x7f, 0x8a, 0xa4, 0xaa,
-    0xaf, 0xb0, 0xc0, 0xd0, 0x2f, 0x3f,
+    0x56, 0xf3, 0xd0, 0xd1, 0x04, 0x14, 0x18, 0x36,
+    0x37, 0x56, 0x57, 0xbd, 0x35, 0xce, 0xcf, 0xe0,
+    0x12, 0x87, 0x89, 0x8e, 0x9e, 0x04, 0x0d, 0x0e,
+    0x11, 0x12, 0x29, 0x31, 0x34, 0x3a, 0x45, 0x46,
+    0x49, 0x4a, 0x4e, 0x4f, 0x64, 0x65, 0x5a, 0x5c,
+    0xb6, 0xb7, 0x1b, 0x1c, 0x84, 0x85, 0x09, 0x37,
+    0x90, 0x91, 0xa8, 0x07, 0x0a, 0x3b, 0x3e, 0x66,
+    0x69, 0x8f, 0x92, 0x6f, 0x5f, 0xee, 0xef, 0x5a,
+    0x62, 0x9a, 0x9b, 0x27, 0x28, 0x55, 0x9d, 0xa0,
+    0xa1, 0xa3, 0xa4, 0xa7, 0xa8, 0xad, 0xba, 0xbc,
+    0xc4, 0x06, 0x0b, 0x0c, 0x15, 0x1d, 0x3a, 0x3f,
+    0x45, 0x51, 0xa6, 0xa7, 0xcc, 0xcd, 0xa0, 0x07,
+    0x19, 0x1a, 0x22, 0x25, 0xc5, 0xc6, 0x04, 0x20,
+    0x23, 0x25, 0x26, 0x28, 0x33, 0x38, 0x3a, 0x48,
+    0x4a, 0x4c, 0x50, 0x53, 0x55, 0x56, 0x58, 0x5a,
+    0x5c, 0x5e, 0x60, 0x63, 0x65, 0x66, 0x6b, 0x73,
+    0x78, 0x7d, 0x7f, 0x8a, 0xa4, 0xaa, 0xaf, 0xb0,
+    0xc0, 0xd0, 0x3f, 0x71, 0x72, 0x7b,
 ];
 const NORMAL0: &'static [u8] = &[
     0x00, 0x20,
     0x5f, 0x22,
     0x82, 0xdf, 0x04,
     0x82, 0x44, 0x08,
-    0x1b, 0x05,
-    0x05, 0x11,
+    0x1b, 0x04,
+    0x06, 0x11,
     0x81, 0xac, 0x0e,
-    0x3b, 0x05,
-    0x6b, 0x35,
-    0x1e, 0x16,
-    0x80, 0xdf, 0x03,
+    0x80, 0xab, 0x35,
+    0x1e, 0x15,
+    0x80, 0xe0, 0x03,
     0x19, 0x08,
     0x01, 0x04,
-    0x22, 0x03,
-    0x0a, 0x04,
+    0x2f, 0x04,
     0x34, 0x04,
     0x07, 0x03,
     0x01, 0x07,
     0x06, 0x07,
-    0x10, 0x0b,
+    0x11, 0x0a,
     0x50, 0x0f,
     0x12, 0x07,
     0x55, 0x08,
@@ -286,7 +284,7 @@
     0x6a, 0x06,
     0x0a, 0x06,
     0x1a, 0x06,
-    0x58, 0x08,
+    0x59, 0x07,
     0x2b, 0x05,
     0x46, 0x0a,
     0x2c, 0x04,
@@ -304,8 +302,8 @@
     0x74, 0x08,
     0x3c, 0x03,
     0x0f, 0x03,
-    0x3c, 0x37,
-    0x08, 0x08,
+    0x3c, 0x07,
+    0x38, 0x08,
     0x2a, 0x06,
     0x82, 0xff, 0x11,
     0x18, 0x08,
@@ -316,15 +314,12 @@
     0x80, 0x8c, 0x04,
     0x82, 0x97, 0x19,
     0x0b, 0x15,
-    0x87, 0x5a, 0x03,
-    0x16, 0x19,
-    0x04, 0x10,
-    0x80, 0xf4, 0x05,
+    0x88, 0x94, 0x05,
     0x2f, 0x05,
     0x3b, 0x07,
     0x02, 0x0e,
     0x18, 0x09,
-    0x80, 0xaa, 0x36,
+    0x80, 0xaf, 0x31,
     0x74, 0x0c,
     0x80, 0xd6, 0x1a,
     0x0c, 0x05,
@@ -332,12 +327,12 @@
     0x80, 0xb6, 0x05,
     0x24, 0x0c,
     0x9b, 0xc6, 0x0a,
-    0xd2, 0x2b, 0x15,
+    0xd2, 0x30, 0x10,
     0x84, 0x8d, 0x03,
     0x37, 0x09,
     0x81, 0x5c, 0x14,
     0x80, 0xb8, 0x08,
-    0x80, 0xb8, 0x3f,
+    0x80, 0xba, 0x3d,
     0x35, 0x04,
     0x0a, 0x06,
     0x38, 0x08,
@@ -402,9 +397,8 @@
     0x01, 0x40,
     0x38, 0x04,
     0x4b, 0x05,
-    0x28, 0x04,
-    0x03, 0x04,
-    0x09, 0x08,
+    0x2f, 0x04,
+    0x0a, 0x07,
     0x09, 0x07,
     0x40, 0x20,
     0x27, 0x04,
@@ -417,14 +411,17 @@
     0x49, 0x37,
     0x33, 0x0d,
     0x33, 0x07,
-    0x06, 0x81, 0x60,
-    0x1f, 0x81, 0x81,
+    0x2e, 0x08,
+    0x0a, 0x81, 0x26,
+    0x1f, 0x80, 0x81,
+    0x28, 0x08,
+    0x2a, 0x80, 0xa6,
     0x4e, 0x04,
     0x1e, 0x0f,
     0x43, 0x0e,
     0x19, 0x07,
     0x0a, 0x06,
-    0x44, 0x0c,
+    0x47, 0x09,
     0x27, 0x09,
     0x75, 0x0b,
     0x3f, 0x41,
@@ -435,7 +432,7 @@
     0x01, 0x05,
     0x10, 0x03,
     0x05, 0x80, 0x8b,
-    0x5e, 0x22,
+    0x5f, 0x21,
     0x48, 0x08,
     0x0a, 0x80, 0xa6,
     0x5e, 0x22,
@@ -444,9 +441,9 @@
     0x0d, 0x13,
     0x38, 0x08,
     0x0a, 0x36,
-    0x1a, 0x03,
-    0x0f, 0x04,
-    0x10, 0x81, 0x60,
+    0x2c, 0x04,
+    0x10, 0x80, 0xc0,
+    0x3c, 0x64,
     0x53, 0x0c,
     0x01, 0x81, 0x00,
     0x48, 0x08,
@@ -457,7 +454,10 @@
     0x47, 0x49,
     0x37, 0x03,
     0x0e, 0x08,
-    0x0a, 0x82, 0xa6,
+    0x0a, 0x06,
+    0x39, 0x07,
+    0x0a, 0x81, 0x36,
+    0x19, 0x81, 0x07,
     0x83, 0x9a, 0x66,
     0x75, 0x0b,
     0x80, 0xc4, 0x8a, 0xbc,
@@ -469,12 +469,13 @@
     0x26, 0x0a,
     0x46, 0x0a,
     0x28, 0x05,
-    0x13, 0x83, 0x70,
+    0x13, 0x82, 0xb0,
+    0x5b, 0x65,
     0x45, 0x0b,
     0x2f, 0x10,
     0x11, 0x40,
     0x02, 0x1e,
-    0x97, 0xed, 0x13,
+    0x97, 0xf2, 0x0e,
     0x82, 0xf3, 0xa5, 0x0d,
     0x81, 0x1f, 0x51,
     0x81, 0x8c, 0x89, 0x04,
@@ -485,9 +486,10 @@
     0x80, 0xf6, 0x0a,
     0x73, 0x08,
     0x6e, 0x17,
-    0x46, 0x80, 0xba,
+    0x46, 0x80, 0x9a,
+    0x14, 0x0c,
     0x57, 0x09,
-    0x12, 0x80, 0x8e,
+    0x19, 0x80, 0x87,
     0x81, 0x47, 0x03,
     0x85, 0x42, 0x0f,
     0x15, 0x85, 0x50,
@@ -495,7 +497,8 @@
     0x80, 0xd7, 0x29,
     0x4b, 0x05,
     0x0a, 0x04,
-    0x02, 0x84, 0xa0,
+    0x02, 0x83, 0x11,
+    0x44, 0x81, 0x4b,
     0x3c, 0x06,
     0x01, 0x04,
     0x55, 0x05,
@@ -514,18 +517,19 @@
     0x06, 0x80, 0x9a,
     0x83, 0xd5, 0x0b,
     0x0d, 0x03,
-    0x09, 0x07,
+    0x0a, 0x06,
     0x74, 0x0c,
-    0x55, 0x2b,
+    0x59, 0x27,
     0x0c, 0x04,
     0x38, 0x08,
     0x0a, 0x06,
     0x28, 0x08,
     0x1e, 0x52,
     0x0c, 0x04,
-    0x3d, 0x03,
-    0x1c, 0x14,
-    0x18, 0x28,
-    0x01, 0x0f,
-    0x17, 0x86, 0x19,
+    0x67, 0x03,
+    0x29, 0x0d,
+    0x0a, 0x06,
+    0x03, 0x0d,
+    0x30, 0x60,
+    0x0e, 0x85, 0x92,
 ];
diff --git a/src/libcore/unicode/tables.rs b/src/libcore/unicode/tables.rs
index e3d2747..32668ea 100644
--- a/src/libcore/unicode/tables.rs
+++ b/src/libcore/unicode/tables.rs
@@ -19,7 +19,7 @@
 /// `char` and `str` methods are based on.
 #[unstable(feature = "unicode_version", issue = "49726")]
 pub const UNICODE_VERSION: UnicodeVersion = UnicodeVersion {
-    major: 10,
+    major: 11,
     minor: 0,
     micro: 0,
     _priv: (),
@@ -105,10 +105,10 @@
         ],
         r5: &[
             0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 5, 0, 6, 7, 0, 0, 8, 0, 0, 0, 6, 0, 0, 0, 0, 0, 8, 0, 8, 0, 0, 0,
-            0, 0, 8, 0, 9, 6, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0,
-            0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 6, 0, 5, 7, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 0, 0, 8, 0, 8, 0, 0, 0,
+            0, 0, 8, 0, 9, 5, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0,
+            0, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,
             11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -123,7 +123,7 @@
         ],
         r6: &[
             0x0000000000000000, 0x001fffffffffffff, 0x0000000000000402, 0x00000000003e0000,
-            0x000003ff00000000, 0x0000ffc000000000, 0x03ff000000000000, 0xffc0000000000000,
+            0x000003ff00000000, 0x03ff000000000000, 0x0000ffc000000000, 0xffc0000000000000,
             0x0000000003ff0000, 0x00000000000003ff, 0xffffffffffffffff, 0x00007fffffffffff,
             0xffffffffffffc000
         ],
@@ -143,7 +143,7 @@
             0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x0000501f0003ffc3,
             0x0000000000000000, 0xbcdf000000000020, 0xfffffffbffffd740, 0xffbfffffffffffff,
             0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffffc03, 0xffffffffffffffff,
-            0xfffeffffffffffff, 0xfffffffe027fffff, 0xbfff0000000000ff, 0x000707ffffff00b6,
+            0xfffeffffffffffff, 0xffffffff027fffff, 0xbfff0000000001ff, 0x000787ffffff00b6,
             0xffffffff07ff0000, 0xffffc000feffffff, 0xffffffffffffffff, 0x9c00e1fe1fefffff,
             0xffffffffffff0000, 0xffffffffffffe000, 0x0003ffffffffffff, 0x043007fffffffc00
         ],
@@ -152,10 +152,10 @@
             24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 36, 36, 36, 36, 37, 38, 39, 40, 41,
             42, 43, 44, 36, 36, 36, 36, 36, 36, 36, 36, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
             56, 57, 58, 59, 60, 61, 62, 31, 63, 64, 65, 66, 55, 67, 68, 69, 36, 36, 36, 70, 36, 36,
-            36, 36, 71, 72, 73, 74, 31, 75, 76, 31, 77, 78, 68, 31, 31, 31, 31, 31, 31, 31, 31, 31,
-            31, 31, 79, 80, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
-            31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 81, 82, 36, 83, 84, 85, 86, 87, 88, 31, 31, 31,
-            31, 31, 31, 31, 89, 44, 90, 91, 92, 36, 93, 94, 31, 31, 31, 31, 31, 31, 31, 31, 36, 36,
+            36, 36, 71, 72, 73, 74, 31, 75, 76, 31, 77, 78, 79, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+            31, 31, 80, 81, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+            31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 82, 83, 36, 84, 85, 86, 87, 88, 89, 31, 31, 31,
+            31, 31, 31, 31, 90, 44, 91, 92, 93, 36, 94, 95, 31, 31, 31, 31, 31, 31, 31, 31, 36, 36,
             36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
             36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
             36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
@@ -175,9 +175,9 @@
             36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
             36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
             36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
-            36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 95, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
-            36, 36, 36, 36, 36, 36, 36, 36, 96, 97, 36, 36, 36, 36, 98, 99, 36, 100, 101, 36, 102,
-            103, 104, 105, 36, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 36, 95, 36,
+            36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 96, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+            36, 36, 36, 36, 36, 36, 36, 36, 97, 98, 36, 36, 36, 36, 99, 100, 36, 96, 101, 36, 102,
+            103, 104, 105, 36, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 36, 117, 36,
             36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
             36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
             36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
@@ -185,15 +185,15 @@
             36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
             36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
             36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
-            36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 117, 118,
+            36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 118, 119,
             31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
             31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
             31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
             31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
             31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
             31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
-            36, 36, 36, 36, 36, 119, 36, 120, 121, 122, 123, 124, 36, 36, 36, 36, 125, 126, 127,
-            128, 31, 129, 36, 130, 131, 132, 113, 133
+            36, 36, 36, 36, 36, 120, 36, 121, 122, 123, 124, 125, 36, 36, 36, 36, 126, 127, 128,
+            129, 31, 130, 36, 131, 132, 133, 113, 134
         ],
         r3: &[
             0x00001ffffcffffff, 0x000007ff01ffffff, 0x3fdfffff00000000, 0xffff03f8fff00000,
@@ -209,27 +209,27 @@
             0xffffffffff3dffff, 0x0000000087ffffff, 0xffffffff0000ffff, 0x3f3fffffffffffff,
             0xfffffffffffffffe, 0xffff9fffffffffff, 0xffffffff07fffffe, 0x01ffc7ffffffffff,
             0x000fffff000fdfff, 0x000ddfff000fffff, 0xffcfffffffffffff, 0x00000000108001ff,
-            0xffffffff00000000, 0x00ffffffffffffff, 0xffff07ffffffffff, 0x003fffffffffffff,
+            0xffffffff00000000, 0x01ffffffffffffff, 0xffff07ffffffffff, 0x003fffffffffffff,
             0x01ff0fff7fffffff, 0x001f3fffffff0000, 0xffff0fffffffffff, 0x00000000000003ff,
             0xffffffff0fffffff, 0x001ffffe7fffffff, 0x0000008000000000, 0xffefffffffffffff,
             0x0000000000000fef, 0xfc00f3ffffffffff, 0x0003ffbfffffffff, 0x3ffffffffc00e000,
-            0x00000000000001ff, 0x006fde0000000000, 0x001fff8000000000, 0xffffffff3f3fffff,
+            0xe7ffffffffff01ff, 0x006fde0000000000, 0x001fff8000000000, 0xffffffff3f3fffff,
             0x3fffffffaaff3f3f, 0x5fdfffffffffffff, 0x1fdc1fff0fcf1fdc, 0x8002000000000000,
-            0x000000001fff0000, 0xf3ffbd503e2ffc84, 0xffffffff000043e0, 0xffc0000000000000,
-            0x000003ffffffffff, 0xffff7fffffffffff, 0xffffffff7fffffff, 0x000c781fffffffff,
-            0xffff20bfffffffff, 0x000080ffffffffff, 0x7f7f7f7f007fffff, 0xffffffff7f7f7f7f,
-            0x0000800000000000, 0x1f3e03fe000000e0, 0xfffffffee07fffff, 0xf7ffffffffffffff,
-            0xfffe7fffffffffe0, 0x07ffffff00007fff, 0xffff000000000000, 0x000007ffffffffff,
-            0x0000000000001fff, 0x3fffffffffff0000, 0x00000c00ffff1fff, 0x8ff07fffffffffff,
-            0x0000ffffffffffff, 0xfffffffcff800000, 0x00ff7ffffffff9ff, 0xff80000000000000,
-            0x000000fffffff7bb, 0x000fffffffffffff, 0x28fc00000000002f, 0xffff07fffffffc00,
+            0x000000001fff0000, 0xf3ffbd503e2ffc84, 0xffffffff000043e0, 0x00000000000001ff,
+            0xffc0000000000000, 0x000003ffffffffff, 0xffff7fffffffffff, 0xffffffff7fffffff,
+            0x000c781fffffffff, 0xffff20bfffffffff, 0x000080ffffffffff, 0x7f7f7f7f007fffff,
+            0xffffffff7f7f7f7f, 0x0000800000000000, 0x1f3e03fe000000e0, 0xfffffffee07fffff,
+            0xf7ffffffffffffff, 0xfffeffffffffffe0, 0x07ffffff00007fff, 0xffff000000000000,
+            0x0000ffffffffffff, 0x0000000000001fff, 0x3fffffffffff0000, 0x00000c00ffff1fff,
+            0x8ff07fffffffffff, 0xfffffffcff800000, 0x03fffffffffff9ff, 0xff80000000000000,
+            0x000000fffffff7bb, 0x000fffffffffffff, 0x68fc00000000002f, 0xffff07fffffffc00,
             0x1fffffff0007ffff, 0xfff7ffffffffffff, 0x7c00ffdf00008000, 0x007fffffffffffff,
             0xc47fffff00003fff, 0x7fffffffffffffff, 0x003cffff38000005, 0xffff7f7f007e7e7e,
-            0xffff003ff7ffffff, 0xffff000fffffffff, 0x0ffffffffffff87f, 0xffff3fffffffffff,
-            0x0000000003ffffff, 0x5f7ffdffe0f8007f, 0xffffffffffffffdb, 0x0003ffffffffffff,
-            0xfffffffffff80000, 0x3fffffffffffffff, 0xffffffffffff0000, 0xfffffffffffcffff,
-            0x0fff0000000000ff, 0xffdf000000000000, 0x1fffffffffffffff, 0x07fffffe00000000,
-            0xffffffc007fffffe, 0x000000001cfcfcfc
+            0xffff003ff7ffffff, 0x000007ffffffffff, 0xffff000fffffffff, 0x0ffffffffffff87f,
+            0xffff3fffffffffff, 0x0000000003ffffff, 0x5f7ffdffe0f8007f, 0xffffffffffffffdb,
+            0x0003ffffffffffff, 0xfffffffffff80000, 0x3fffffffffffffff, 0xffffffffffff0000,
+            0xfffffffffffcffff, 0x0fff0000000000ff, 0xffdf000000000000, 0x1fffffffffffffff,
+            0x07fffffe00000000, 0xffffffc007fffffe, 0x000000001cfcfcfc
         ],
         r4: [
             0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 10, 11, 12, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 13, 14,
@@ -245,45 +245,45 @@
         r5: &[
             0, 1, 2, 3, 4, 5, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 2, 2, 12, 13, 14, 15, 4, 4, 2, 2, 2,
             2, 16, 17, 4, 4, 18, 19, 20, 21, 22, 4, 23, 4, 24, 25, 26, 27, 28, 29, 30, 4, 2, 31, 32,
-            32, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 33, 34, 35, 32, 36, 2, 37, 38, 4, 39, 40, 41,
-            42, 4, 4, 2, 43, 2, 44, 4, 4, 45, 46, 47, 48, 28, 4, 49, 4, 4, 4, 4, 4, 50, 51, 4, 4, 4,
-            4, 52, 53, 54, 55, 4, 4, 4, 4, 56, 57, 58, 4, 59, 60, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 61, 4, 2, 62, 2, 2, 2, 63, 4, 4, 4, 4, 4, 4, 4,
+            32, 33, 4, 4, 4, 4, 4, 4, 4, 34, 35, 4, 4, 2, 35, 36, 37, 32, 38, 2, 39, 40, 4, 41, 42,
+            43, 44, 4, 4, 2, 45, 2, 46, 4, 4, 47, 48, 49, 50, 28, 4, 51, 4, 4, 4, 52, 4, 53, 54, 4,
+            4, 4, 4, 55, 56, 57, 52, 4, 4, 4, 4, 58, 59, 60, 4, 61, 62, 63, 4, 4, 4, 4, 64, 4, 4, 4,
+            4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 65, 4, 2, 66, 2, 2, 2, 67, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 62, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 66, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 64, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 68, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2,
-            2, 2, 2, 2, 2, 2, 55, 20, 4, 65, 16, 66, 67, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2,
-            68, 69, 70, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            2, 2, 2, 2, 2, 2, 2, 2, 52, 20, 4, 69, 16, 70, 71, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4,
+            4, 2, 72, 73, 74, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 71, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 32, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 20, 72, 2, 2, 2, 2, 2, 73,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 75, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 32, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 20, 76, 2, 2, 2, 2, 2,
+            77, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 2, 78, 79, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 80, 81, 82, 83, 84, 2, 2, 2, 2, 85, 86, 87, 88, 89,
+            90, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 91, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 92, 2, 93, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 94, 95, 96, 4, 4, 4, 4, 4, 4, 4, 4, 4, 76, 97, 98, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 2, 74, 75, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 76, 77, 78, 79, 80, 2, 2, 2, 2, 81, 82, 83, 84, 85, 86,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 87, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 2, 2, 2, 88, 2, 89, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 90, 91, 92, 4, 4, 4, 4, 4, 4, 4, 4, 4, 72, 93, 94, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 95, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 99, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 10, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 10, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            96, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 97, 4, 4, 4, 4,
+            2, 100, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 101, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 98, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 102, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
         ],
         r6: &[
             0xb7ffff7fffffefff, 0x000000003fff3fff, 0xffffffffffffffff, 0x07ffffffffffffff,
@@ -292,18 +292,19 @@
             0xffff00003fffffff, 0x0fffffffff0fffff, 0xffff00ffffffffff, 0x0000000fffffffff,
             0x007fffffffffffff, 0x000000ff003fffff, 0x91bffffffffffd3f, 0x007fffff003fffff,
             0x000000007fffffff, 0x0037ffff00000000, 0x03ffffff003fffff, 0xc0ffffffffffffff,
-            0x000ffffffeeff06f, 0x1fffffff00000000, 0x000000001fffffff, 0x0000001ffffffeff,
+            0x003ffffffeeff06f, 0x1fffffff00000000, 0x000000001fffffff, 0x0000001ffffffeff,
             0x003fffffffffffff, 0x0007ffff003fffff, 0x000000000003ffff, 0x00000000000001ff,
-            0x0007ffffffffffff, 0x000000000000003f, 0x01fffffffffffffc, 0x000001ffffff0000,
-            0x0047ffffffff0000, 0x000000001400001e, 0x409ffffffffbffff, 0xffff01ffbfffbd7f,
-            0x000001ffffffffff, 0xe3edfdfffff99fef, 0x0000000fe081199f, 0x00000000000007bb,
-            0x00000000000000b3, 0x7f3fffffffffffff, 0x000000003f000000, 0x7fffffffffffffff,
-            0x0000000000000011, 0x000007ffe3ffffff, 0xffffffff00000000, 0x80000000ffffffff,
-            0x7fe7ffffffffffff, 0xffffffffffff0000, 0x0000000000ffffcf, 0x01ffffffffffffff,
-            0x7f7ffffffffffdff, 0xfffc000000000001, 0x007ffefffffcffff, 0xb47ffffffffffb7f,
-            0x00000000000000cb, 0x0000000003ffffff, 0x00007fffffffffff, 0x000000000000000f,
+            0x0007ffffffffffff, 0x000000ffffffffff, 0xffff00801fffffff, 0x000000000000003f,
+            0x01fffffffffffffc, 0x000001ffffff0000, 0x0047ffffffff0070, 0x000000001400001e,
+            0x409ffffffffbffff, 0xffff01ffbfffbd7f, 0x000001ffffffffff, 0xe3edfdfffff99fef,
+            0x0000000fe081199f, 0x00000000000007bb, 0x00000000000000b3, 0x7f3fffffffffffff,
+            0x000000003f000000, 0x7fffffffffffffff, 0x0000000000000011, 0x000007ffe7ffffff,
+            0x01ffffffffffffff, 0xffffffff00000000, 0x80000000ffffffff, 0x7fe7ffffffffffff,
+            0xffffffffffff0000, 0x0000000020ffffcf, 0x7f7ffffffffffdff, 0xfffc000000000001,
+            0x007ffefffffcffff, 0xb47ffffffffffb7f, 0xfffffdbf000000cb, 0x00000000017b7fff,
+            0x007fffff00000000, 0x0000000003ffffff, 0x00007fffffffffff, 0x000000000000000f,
             0x000000000000007f, 0x00003fffffff0000, 0xe0fffff80000000f, 0x000000000000ffff,
-            0x7fffffffffff001f, 0x00000000fff80000, 0x0000000300000000, 0x00001fffffffffff,
+            0x7fffffffffff001f, 0x00000000fff80000, 0x0000000300000000, 0x0003ffffffffffff,
             0xffff000000000000, 0x0fffffffffffffff, 0x1fff07ffffffffff, 0x0000000043ff01ff,
             0xffffffffffdfffff, 0xebffde64dfffffff, 0xffffffffffffffef, 0x7bffffffdfdfe7bf,
             0xfffffffffffdfc5f, 0xffffff3fffffffff, 0xf7fffffff7fffffd, 0xffdfffffffdfffff,
@@ -327,16 +328,16 @@
             0x0000000000000000, 0x0000000000000000, 0x00000000000003f8, 0x0000000000000000,
             0x0000000000000000, 0x0000000002000000, 0xbffffffffffe0000, 0x00100000000000b6,
             0x0000000017ff003f, 0x00010000fffff801, 0x0000000000000000, 0x00003dffbfc00000,
-            0xffff000000028000, 0x00000000000007ff, 0x0001ffc000000000, 0x043ff80000000000
+            0xffff000000028000, 0x00000000000007ff, 0x0001ffc000000000, 0x243ff80000000000
         ],
         r2: [
-            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 10, 11, 12, 13, 14, 15, 16, 11, 17, 18, 7, 2, 19, 20,
-            21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 2, 2, 2, 2, 2, 2, 2, 2, 2, 32, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, 34, 35, 36, 37, 38, 39, 2, 40, 2, 2, 2, 41, 42, 43, 2,
-            44, 45, 46, 47, 48, 49, 2, 50, 51, 52, 53, 54, 2, 2, 2, 2, 2, 2, 55, 56, 57, 58, 59, 60,
+            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 10, 11, 12, 13, 14, 15, 16, 11, 17, 18, 19, 2, 20, 21,
+            22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 34, 35, 36, 37, 38, 39, 40, 2, 41, 2, 2, 2, 42, 43, 44, 2,
+            45, 46, 47, 48, 49, 50, 2, 51, 52, 53, 54, 55, 2, 2, 2, 2, 2, 2, 56, 57, 58, 59, 60, 61,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 61, 2, 62, 2, 63, 2, 64, 65, 2, 2, 2, 2,
-            2, 2, 2, 66, 2, 67, 68, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 62, 2, 63, 2, 64, 2, 65, 66, 2, 2, 2, 2,
+            2, 2, 2, 67, 2, 68, 69, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -351,9 +352,9 @@
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 49, 2, 2, 2, 2, 70, 71, 72, 73, 74, 75, 76, 77, 78, 2, 2, 79, 80,
-            81, 82, 83, 84, 85, 86, 87, 2, 88, 2, 89, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 70, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 50, 2, 2, 2, 2, 71, 72, 73, 74, 75, 76, 77, 78, 79, 2, 2, 80, 81,
+            82, 83, 84, 85, 86, 87, 88, 2, 89, 2, 90, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -364,35 +365,36 @@
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 90, 2, 91, 92, 2, 2, 2, 2, 2, 2, 2, 2, 93, 94, 2, 95,
-            96, 97, 98, 99
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 91, 2, 92, 93, 2, 2, 2, 2, 2, 2, 2, 2, 94, 95, 2, 96,
+            97, 98, 99, 100
         ],
         r3: &[
-            0x00003fffffc00000, 0x000000000e000000, 0x0000000000000000, 0xfffffffffff00000,
-            0x1400000000000007, 0x0002000c00fe21fe, 0x1000000000000002, 0x0000000c0000201e,
+            0x00003fffffc00000, 0x000000000e000000, 0x0000000000000000, 0xfffffffffff80000,
+            0x1400000000000007, 0x0002000c00fe21fe, 0x1000000000000002, 0x4000000c0000201e,
             0x1000000000000006, 0x0023000000023986, 0xfc00000c000021be, 0x9000000000000002,
-            0x0000000c0040201e, 0x0000000000000004, 0x0000000000002001, 0xc000000000000001,
-            0x0000000c00603dc1, 0x0000000c00003040, 0x1800000000000003, 0x00000000005c0400,
-            0x07f2000000000000, 0x0000000000007fc0, 0x1bf2000000000000, 0x0000000000003f40,
-            0x02a0000003000000, 0x7ffe000000000000, 0x1ffffffffeffe0df, 0x0000000000000040,
-            0x66fde00000000000, 0x001e0001c3000000, 0x0000000020002064, 0x1000000000000000,
-            0x00000000e0000000, 0x001c0000001c0000, 0x000c0000000c0000, 0x3fb0000000000000,
-            0x00000000208ffe40, 0x0000000000007800, 0x0000000000000008, 0x0000020000000060,
-            0x0e04018700000000, 0x0000000009800000, 0x9ff81fe57f400000, 0x7fff008000000000,
-            0x17d000000000000f, 0x000ff80000000004, 0x00003b3c00000003, 0x0003a34000000000,
-            0x00cff00000000000, 0x3f00000000000000, 0x031021fdfff70000, 0xfffff00000000000,
-            0x010007ffffffffff, 0xfffffffff8000000, 0xfbffffffffffffff, 0xa000000000000000,
-            0x6000e000e000e003, 0x00007c900300f800, 0x8002ffdf00000000, 0x000000001fff0000,
-            0x0001ffffffff0000, 0x3000000000000000, 0x0003800000000000, 0x8000800000000000,
-            0xffffffff00000000, 0x0000800000000000, 0x083e3c0000000020, 0x000000007e000000,
-            0x7000000000000000, 0x0000000000200000, 0x0000000000001000, 0xbff7800000000000,
-            0x00000000f0000000, 0x0003000000000000, 0x00000003ffffffff, 0x0001000000000000,
-            0x0000000000000700, 0x0300000000000000, 0x0000006000000844, 0x0003ffff00000030,
-            0x00003fc000000000, 0x000000000003ff80, 0x13c8000000000007, 0x0000006000008000,
-            0x00667e0000000000, 0x1001000000001008, 0xc19d000000000000, 0x0058300020000002,
-            0x00000000f8000000, 0x0000212000000000, 0x0000000040000000, 0xfffc000000000000,
-            0x0000000000000003, 0x0000ffff0008ffff, 0x0000000000240000, 0x8000000000000000,
-            0x4000000004004080, 0x0001000000000001, 0x00000000c0000000, 0x0e00000800000000
+            0x0000000c0040201e, 0x0000000000000004, 0x0000000000002001, 0xc000000000000011,
+            0x0000000c00603dc1, 0x0000000c00003040, 0x1800000000000003, 0x0000000c0000201e,
+            0x00000000005c0400, 0x07f2000000000000, 0x0000000000007fc0, 0x1bf2000000000000,
+            0x0000000000003f40, 0x02a0000003000000, 0x7ffe000000000000, 0x1ffffffffeffe0df,
+            0x0000000000000040, 0x66fde00000000000, 0x001e0001c3000000, 0x0000000020002064,
+            0x1000000000000000, 0x00000000e0000000, 0x001c0000001c0000, 0x000c0000000c0000,
+            0x3fb0000000000000, 0x00000000208ffe40, 0x0000000000007800, 0x0000000000000008,
+            0x0000020000000060, 0x0e04018700000000, 0x0000000009800000, 0x9ff81fe57f400000,
+            0x7fff008000000000, 0x17d000000000000f, 0x000ff80000000004, 0x00003b3c00000003,
+            0x0003a34000000000, 0x00cff00000000000, 0x3f00000000000000, 0x031021fdfff70000,
+            0xfffff00000000000, 0x010007ffffffffff, 0xfffffffff8000000, 0xfbffffffffffffff,
+            0xa000000000000000, 0x6000e000e000e003, 0x00007c900300f800, 0x8002ffdf00000000,
+            0x000000001fff0000, 0x0001ffffffff0000, 0x3000000000000000, 0x0003800000000000,
+            0x8000800000000000, 0xffffffff00000000, 0x0000800000000000, 0x083e3c0000000020,
+            0x000000007e000000, 0x7000000000000000, 0x0000000000200000, 0x0000000000001000,
+            0xbff7800000000000, 0x00000000f0000000, 0x0003000000000000, 0x00000003ffffffff,
+            0x0001000000000000, 0x0000000000000700, 0x0300000000000000, 0x0000006000000844,
+            0x8003ffff00000030, 0x00003fc000000000, 0x000000000003ff80, 0x13c8000000000007,
+            0x0000006000008000, 0x00667e0000000000, 0x1001000000001008, 0xc19d000000000000,
+            0x0058300020000002, 0x00000000f8000000, 0x0000212000000000, 0x0000000040000000,
+            0xfffc000000000000, 0x0000000000000003, 0x0000ffff0008ffff, 0x0000000000240000,
+            0x8000000000000000, 0x4000000004004080, 0x0001000000000001, 0x00000000c0000000,
+            0x0e00000800000000
         ],
         r4: [
             0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 4, 2, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -407,42 +409,43 @@
         ],
         r5: &[
             0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 6, 7, 8, 0, 9, 10, 11, 12, 13, 0, 0, 14, 15, 16, 0, 0, 17, 18, 19, 20,
-            0, 0, 21, 22, 23, 24, 25, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, 0, 0, 0,
-            0, 0, 30, 0, 31, 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
+            0, 0, 0, 7, 0, 0, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 17, 18, 19, 0, 0, 20, 21, 22,
+            23, 0, 0, 24, 25, 26, 27, 28, 0, 29, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 31, 32, 33, 0, 0,
+            0, 0, 0, 34, 0, 35, 0, 36, 37, 38, 0, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 35, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 37, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 41, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 45, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, 48, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 43, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 47, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 51, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 0, 54, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            50, 51, 0, 0, 51, 51, 51, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 56, 57, 0, 0, 57, 57, 57, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0
         ],
         r6: &[
             0x0000000000000000, 0x2000000000000000, 0x0000000100000000, 0x07c0000000000000,
-            0x870000000000f06e, 0x0000006000000000, 0xff00000000000002, 0x800000000000007f,
-            0x2678000000000003, 0x001fef8000000007, 0x0008000000000000, 0x7fc0000000000003,
-            0x0000000000001c00, 0x40d3800000000000, 0x000007f880000000, 0x1000000000000003,
-            0x001f1fc000000001, 0xff00000000000000, 0x000000000000005c, 0x85f8000000000000,
-            0x000000000000000d, 0xb03c000000000000, 0x0000000030000001, 0xa7f8000000000000,
-            0x0000000000000001, 0x00bf280000000000, 0x00000fbce0000000, 0x79f800000000067e,
+            0x870000000000f06e, 0x0000006000000000, 0x000000f000000000, 0x000000000001ffc0,
+            0xff00000000000002, 0x800000000000007f, 0x2678000000000003, 0x0000000000002000,
+            0x001fef8000000007, 0x0008000000000000, 0x7fc0000000000003, 0x0000000000001e00,
+            0x40d3800000000000, 0x000007f880000000, 0x1800000000000003, 0x001f1fc000000001,
+            0xff00000000000000, 0x000000004000005c, 0x85f8000000000000, 0x000000000000000d,
+            0xb03c000000000000, 0x0000000030000001, 0xa7f8000000000000, 0x0000000000000001,
+            0x00bf280000000000, 0x00000fbce0000000, 0x06ff800000000000, 0x79f80000000007fe,
             0x000000000e7e0080, 0x00000000037ffc00, 0xbf7f000000000000, 0x006dfcfffffc0000,
-            0xb47e000000000000, 0x00000000000000bf, 0x001f000000000000, 0x007f000000000000,
-            0x000000000000000f, 0x00000000ffff8000, 0x0000000300000000, 0x0000000f60000000,
-            0xfff8038000000000, 0x00003c0000000fe7, 0x000000000000001c, 0xf87fffffffffffff,
-            0x00201fffffffffff, 0x0000fffef8000010, 0x000007dbf9ffff7f, 0x00000000007f0000,
-            0x00000000000007f0, 0xf800000000000000, 0xffffffff00000002, 0xffffffffffffffff,
-            0x0000ffffffffffff
+            0xb47e000000000000, 0x00000000000000bf, 0x0000000000a30000, 0x0018000000000000,
+            0x001f000000000000, 0x007f000000000000, 0x000000000000000f, 0x00000000ffff8000,
+            0x0000000300000000, 0x0000000f60000000, 0xfff8038000000000, 0x00003c0000000fe7,
+            0x000000000000001c, 0xf87fffffffffffff, 0x00201fffffffffff, 0x0000fffef8000010,
+            0x000007dbf9ffff7f, 0x00000000007f0000, 0x00000000000007f0, 0xf800000000000000,
+            0xffffffff00000002, 0xffffffffffffffff, 0x0000ffffffffffff
         ],
     };
 
@@ -457,7 +460,7 @@
             0xffffffffffffffff, 0xffffffffffffffff, 0x01ffffffffefffff, 0x0000001f00000003,
             0x0000000000000000, 0xbccf000000000020, 0xfffffffbffffd740, 0xffbfffffffffffff,
             0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffffc03, 0xffffffffffffffff,
-            0xfffeffffffffffff, 0xfffffffe007fffff, 0x00000000000000ff, 0x0000000000000000,
+            0xfffeffffffffffff, 0xffffffff007fffff, 0x00000000000001ff, 0x0000000000000000,
             0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
             0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000
         ],
@@ -499,17 +502,17 @@
             0, 0, 0, 0, 0, 0, 29, 30, 0, 0
         ],
         r3: &[
-            0x0000000000000000, 0xffffffff00000000, 0x00000000000020bf, 0x3f3fffffffffffff,
-            0x00000000000001ff, 0xffffffffffffffff, 0xffffffff3f3fffff, 0x3fffffffaaff3f3f,
+            0x0000000000000000, 0xffffffff00000000, 0xe7ffffffffff20bf, 0x3f3fffffffffffff,
+            0xe7ffffffffff01ff, 0xffffffffffffffff, 0xffffffff3f3fffff, 0x3fffffffaaff3f3f,
             0x5fdfffffffffffff, 0x1fdc1fff0fcf1fdc, 0x8002000000000000, 0x000000001fff0000,
             0xf21fbd503e2ffc84, 0xffffffff000043e0, 0x0000000000000018, 0xffc0000000000000,
             0x000003ffffffffff, 0xffff7fffffffffff, 0xffffffff7fffffff, 0x000c781fffffffff,
             0x000020bfffffffff, 0x00003fffffffffff, 0x000000003fffffff, 0xfffffffc00000000,
-            0x00ff7fffffff78ff, 0x0700000000000000, 0xffff000000000000, 0xffff003ff7ffffff,
+            0x03ffffffffff78ff, 0x0700000000000000, 0xffff000000000000, 0xffff003ff7ffffff,
             0x0000000000f8007f, 0x07fffffe00000000, 0x0000000007fffffe
         ],
         r4: [
-            0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 4, 5, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -527,13 +530,15 @@
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 1, 8, 9, 10, 11, 12, 1, 1, 1, 1, 13, 14, 15, 16, 17, 18, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 9, 10, 11, 12, 1, 1, 1, 1, 13, 14, 15, 16, 17,
+            18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 1, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 3, 20, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 20, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
         ],
         r6: &[
             0x0000000000000000, 0xffffffffffffffff, 0x000000000000ffff, 0xffff000000000000,
@@ -558,16 +563,16 @@
             0x0000000000000000, 0x0000000000000000, 0x00000000000003f8, 0x0000000000000000,
             0x0000000000000000, 0x0000000000000000, 0xbffffffffffe0000, 0x00000000000000b6,
             0x0000000007ff0000, 0x00010000fffff800, 0x0000000000000000, 0x00003d9f9fc00000,
-            0xffff000000020000, 0x00000000000007ff, 0x0001ffc000000000, 0x000ff80000000000
+            0xffff000000020000, 0x00000000000007ff, 0x0001ffc000000000, 0x200ff80000000000
         ],
         r2: [
-            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 7, 2, 20, 21,
-            22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 32, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 33, 34, 35, 36, 37, 2, 38, 2, 39, 2, 2, 2, 40, 41, 42, 2, 43,
-            44, 45, 46, 47, 2, 2, 48, 2, 2, 2, 49, 2, 2, 2, 2, 2, 2, 2, 2, 50, 2, 2, 51, 2, 2, 2, 2,
+            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 2, 21, 22,
+            23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 34, 35, 36, 37, 38, 2, 39, 2, 40, 2, 2, 2, 41, 42, 43, 2, 44,
+            45, 46, 47, 48, 2, 2, 49, 2, 2, 2, 50, 2, 2, 2, 2, 2, 2, 2, 2, 51, 2, 2, 52, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 52, 2, 53, 2, 54, 2, 2, 2, 2, 2, 2, 2, 2, 55,
-            2, 56, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 53, 2, 54, 2, 55, 2, 2, 2, 2, 2, 2, 2, 2, 56,
+            2, 57, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -583,8 +588,8 @@
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 57, 58, 59, 2, 2, 2, 2, 60, 2, 2, 61, 62, 63, 64, 65, 66, 67,
-            68, 69, 2, 2, 2, 70, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 58, 59, 60, 2, 2, 2, 2, 61, 2, 2, 62, 63, 64, 65, 66, 67, 68,
+            69, 70, 2, 2, 2, 71, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -595,28 +600,28 @@
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 71, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 72, 2, 2, 2, 2, 2, 58, 2
+            2, 2, 2, 2, 72, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 73, 2, 2, 2, 2, 2, 59, 2
         ],
         r3: &[
-            0x00003eeffbc00000, 0x000000000e000000, 0x0000000000000000, 0xfffffffbfff00000,
-            0x1400000000000007, 0x0000000c00fe21fe, 0x5000000000000002, 0x0000000c0080201e,
+            0x00003eeffbc00000, 0x000000000e000000, 0x0000000000000000, 0xfffffffbfff80000,
+            0x1400000000000007, 0x0000000c00fe21fe, 0x5000000000000002, 0x4000000c0080201e,
             0x1000000000000006, 0x0023000000023986, 0xfc00000c000021be, 0xd000000000000002,
-            0x0000000c00c0201e, 0x4000000000000004, 0x0000000000802001, 0xc000000000000001,
+            0x0000000c00c0201e, 0x4000000000000004, 0x0000000000802001, 0xc000000000000011,
             0x0000000c00603dc1, 0x9000000000000002, 0x0000000c00603044, 0x5800000000000003,
-            0x00000000805c8400, 0x07f2000000000000, 0x0000000000007f80, 0x1bf2000000000000,
-            0x0000000000003f00, 0x02a0000003000000, 0x7ffe000000000000, 0x1ffffffffeffe0df,
-            0x0000000000000040, 0x66fde00000000000, 0x001e0001c3000000, 0x0000000020002064,
-            0x00000000e0000000, 0x001c0000001c0000, 0x000c0000000c0000, 0x3fb0000000000000,
-            0x00000000200ffe40, 0x0000000000003800, 0x0000020000000060, 0x0e04018700000000,
-            0x0000000009800000, 0x9ff81fe57f400000, 0x7fff000000000000, 0x17d000000000000f,
-            0x000ff80000000004, 0x00003b3c00000003, 0x0003a34000000000, 0x00cff00000000000,
-            0x031021fdfff70000, 0xfbffffffffffffff, 0x0000000000001000, 0x0001ffffffff0000,
-            0x0003800000000000, 0x8000000000000000, 0xffffffff00000000, 0x0000fc0000000000,
-            0x0000000006000000, 0x3ff7800000000000, 0x00000000c0000000, 0x0003000000000000,
-            0x0000006000000844, 0x0003ffff00000030, 0x00003fc000000000, 0x000000000003ff80,
-            0x13c8000000000007, 0x0000002000000000, 0x00667e0000000000, 0x1000000000001008,
-            0xc19d000000000000, 0x0040300000000002, 0x0000212000000000, 0x0000000040000000,
-            0x0000ffff0000ffff
+            0x0000000c0080201e, 0x00000000805c8400, 0x07f2000000000000, 0x0000000000007f80,
+            0x1bf2000000000000, 0x0000000000003f00, 0x02a0000003000000, 0x7ffe000000000000,
+            0x1ffffffffeffe0df, 0x0000000000000040, 0x66fde00000000000, 0x001e0001c3000000,
+            0x0000000020002064, 0x00000000e0000000, 0x001c0000001c0000, 0x000c0000000c0000,
+            0x3fb0000000000000, 0x00000000200ffe40, 0x0000000000003800, 0x0000020000000060,
+            0x0e04018700000000, 0x0000000009800000, 0x9ff81fe57f400000, 0x7fff000000000000,
+            0x17d000000000000f, 0x000ff80000000004, 0x00003b3c00000003, 0x0003a34000000000,
+            0x00cff00000000000, 0x031021fdfff70000, 0xfbffffffffffffff, 0x0000000000001000,
+            0x0001ffffffff0000, 0x0003800000000000, 0x8000000000000000, 0xffffffff00000000,
+            0x0000fc0000000000, 0x0000000006000000, 0x3ff7800000000000, 0x00000000c0000000,
+            0x0003000000000000, 0x0000006000000844, 0x8003ffff00000030, 0x00003fc000000000,
+            0x000000000003ff80, 0x13c8000000000007, 0x0000002000000000, 0x00667e0000000000,
+            0x1000000000001008, 0xc19d000000000000, 0x0040300000000002, 0x0000212000000000,
+            0x0000000040000000, 0x0000ffff0000ffff
         ],
         r4: [
             0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 4, 2, 5, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -631,38 +636,40 @@
         ],
         r5: &[
             0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 6, 7, 8, 0, 9, 10, 11, 12, 13, 0, 0, 14, 15, 16, 0, 0, 17, 18, 19, 20,
-            0, 0, 21, 22, 23, 24, 25, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, 0, 0, 0,
-            0, 0, 30, 0, 31, 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
+            0, 0, 0, 7, 0, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, 0, 0, 16, 17, 18, 0, 0, 19, 20, 21,
+            22, 0, 0, 23, 24, 25, 26, 27, 0, 28, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 30, 31, 32, 0, 0,
+            0, 0, 0, 33, 0, 34, 0, 35, 36, 37, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 39, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 43, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 46, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 48, 0, 0, 48, 48,
-            48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 47, 48, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 53, 0, 0,
+            53, 53, 53, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0
         ],
         r6: &[
             0x0000000000000000, 0x2000000000000000, 0x0000000100000000, 0x07c0000000000000,
-            0x870000000000f06e, 0x0000006000000000, 0xff00000000000002, 0x800000000000007f,
-            0x0678000000000003, 0x001fef8000000007, 0x0008000000000000, 0x7fc0000000000003,
-            0x0000000000001c00, 0x40d3800000000000, 0x000007f880000000, 0x5000000000000003,
-            0x001f1fc000800001, 0xff00000000000000, 0x000000000000005c, 0xa5f9000000000000,
-            0x000000000000000d, 0xb03c800000000000, 0x0000000030000001, 0xa7f8000000000000,
-            0x0000000000000001, 0x00bf280000000000, 0x00000fbce0000000, 0x79f800000000067e,
-            0x000000000e7e0080, 0x00000000037ffc00, 0xbf7f000000000000, 0x006dfcfffffc0000,
-            0xb47e000000000000, 0x00000000000000bf, 0x001f000000000000, 0x007f000000000000,
-            0x0000000000078000, 0x0000000060000000, 0xf807c3a000000000, 0x00003c0000000fe7,
-            0x000000000000001c, 0xf87fffffffffffff, 0x00201fffffffffff, 0x0000fffef8000010,
-            0x000007dbf9ffff7f, 0x00000000007f0000, 0x00000000000007f0, 0xffffffff00000000,
-            0xffffffffffffffff, 0x0000ffffffffffff
+            0x870000000000f06e, 0x0000006000000000, 0x000000f000000000, 0x000000000001ffc0,
+            0xff00000000000002, 0x800000000000007f, 0x0678000000000003, 0x001fef8000000007,
+            0x0008000000000000, 0x7fc0000000000003, 0x0000000000001e00, 0x40d3800000000000,
+            0x000007f880000000, 0x5800000000000003, 0x001f1fc000800001, 0xff00000000000000,
+            0x000000004000005c, 0xa5f9000000000000, 0x000000000000000d, 0xb03c800000000000,
+            0x0000000030000001, 0xa7f8000000000000, 0x0000000000000001, 0x00bf280000000000,
+            0x00000fbce0000000, 0x06ff800000000000, 0x79f80000000007fe, 0x000000000e7e0080,
+            0x00000000037ffc00, 0xbf7f000000000000, 0x006dfcfffffc0000, 0xb47e000000000000,
+            0x00000000000000bf, 0x0000000000a30000, 0x0018000000000000, 0x001f000000000000,
+            0x007f000000000000, 0x0000000000078000, 0x0000000060000000, 0xf807c3a000000000,
+            0x00003c0000000fe7, 0x000000000000001c, 0xf87fffffffffffff, 0x00201fffffffffff,
+            0x0000fffef8000010, 0x000007dbf9ffff7f, 0x00000000007f0000, 0x00000000000007f0,
+            0xffffffff00000000, 0xffffffffffffffff, 0x0000ffffffffffff
         ],
     };
 
@@ -677,17 +684,17 @@
             0x93faaaaaaaaaaaaa, 0xffffffffffffaa85, 0x01ffffffffefffff, 0x0000001f00000003,
             0x0000000000000000, 0x3c8a000000000020, 0xfffff00000010000, 0x192faaaaaae37fff,
             0xffff000000000000, 0xaaaaaaaaffffffff, 0xaaaaaaaaaaaaa802, 0xaaaaaaaaaaaad554,
-            0x0000aaaaaaaaaaaa, 0xfffffffe00000000, 0x00000000000000ff, 0x0000000000000000,
+            0x0000aaaaaaaaaaaa, 0xffffffff00000000, 0x00000000000001ff, 0x0000000000000000,
             0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
             0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000
         ],
         r2: [
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 3, 3,
-            0, 4, 4, 5, 4, 6, 7, 8, 9, 0, 10, 11, 0, 12, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            16, 17, 4, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4, 4, 4,
+            0, 5, 5, 6, 5, 7, 8, 9, 10, 0, 11, 12, 0, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 17, 18, 5, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -703,8 +710,8 @@
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 0,
-            22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 26, 3, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22,
+            0, 23, 24, 25, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 27, 4, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -715,21 +722,21 @@
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 28, 0, 0
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0
         ],
         r3: &[
-            0x0000000000000000, 0x3f00000000000000, 0x00000000000001ff, 0xffffffffffffffff,
-            0xaaaaaaaaaaaaaaaa, 0xaaaaaaaabfeaaaaa, 0x00ff00ff003f00ff, 0x3fff00ff00ff003f,
-            0x40df00ff00ff00ff, 0x00dc00ff00cf00dc, 0x8002000000000000, 0x000000001fff0000,
-            0x321080000008c400, 0xffff0000000043c0, 0x0000000000000010, 0x000003ffffff0000,
-            0xffff000000000000, 0x3fda15627fffffff, 0x0008501aaaaaaaaa, 0x000020bfffffffff,
-            0x00002aaaaaaaaaaa, 0x000000003aaaaaaa, 0xaaabaaa800000000, 0x95ffaaaaaaaaaaaa,
-            0x00a002aaaaba50aa, 0x0700000000000000, 0xffff003ff7ffffff, 0x0000000000f8007f,
-            0x0000000007fffffe
+            0x0000000000000000, 0xe7ffffffffff0000, 0x3f00000000000000, 0x00000000000001ff,
+            0xffffffffffffffff, 0xaaaaaaaaaaaaaaaa, 0xaaaaaaaabfeaaaaa, 0x00ff00ff003f00ff,
+            0x3fff00ff00ff003f, 0x40df00ff00ff00ff, 0x00dc00ff00cf00dc, 0x8002000000000000,
+            0x000000001fff0000, 0x321080000008c400, 0xffff0000000043c0, 0x0000000000000010,
+            0x000003ffffff0000, 0xffff000000000000, 0x3fda15627fffffff, 0x0008501aaaaaaaaa,
+            0x000020bfffffffff, 0x00002aaaaaaaaaaa, 0x000000003aaaaaaa, 0xaaabaaa800000000,
+            0x95ffaaaaaaaaaaaa, 0x02a082aaaaba50aa, 0x0700000000000000, 0xffff003ff7ffffff,
+            0x0000000000f8007f, 0x0000000007fffffe
         ],
         r4: [
-            0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 4, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -747,19 +754,22 @@
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+            21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 22, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
         ],
         r6: &[
             0x0000000000000000, 0xffffff0000000000, 0x000000000000ffff, 0x0fffffffff000000,
-            0x0007ffffffffffff, 0x00000000ffffffff, 0x000ffffffc000000, 0x000000ffffdfc000,
-            0xebc000000ffffffc, 0xfffffc000000ffef, 0x00ffffffc000000f, 0x00000ffffffc0000,
-            0xfc000000ffffffc0, 0xffffc000000fffff, 0x0ffffffc000000ff, 0x0000ffffffc00000,
-            0x0000003ffffffc00, 0xf0000003f7fffffc, 0xffc000000fdfffff, 0xffff0000003f7fff,
-            0xfffffc000000fdff, 0x0000000000000bf7, 0xfffffffc00000000, 0x000000000000000f
+            0x0007ffffffffffff, 0x00000000ffffffff, 0xffffffff00000000, 0x000ffffffc000000,
+            0x000000ffffdfc000, 0xebc000000ffffffc, 0xfffffc000000ffef, 0x00ffffffc000000f,
+            0x00000ffffffc0000, 0xfc000000ffffffc0, 0xffffc000000fffff, 0x0ffffffc000000ff,
+            0x0000ffffffc00000, 0x0000003ffffffc00, 0xf0000003f7fffffc, 0xffc000000fdfffff,
+            0xffff0000003f7fff, 0xfffffc000000fdff, 0x0000000000000bf7, 0xfffffffc00000000,
+            0x000000000000000f
         ],
     };
 
@@ -781,10 +791,10 @@
         r2: [
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 4, 4, 5, 4, 6, 7, 8, 9, 0, 0, 0, 0, 10, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13,
-            14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            15, 16, 4, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0,
+            0, 5, 5, 6, 5, 7, 8, 9, 10, 0, 0, 0, 0, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14,
+            15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            16, 17, 5, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -800,8 +810,8 @@
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 19, 0,
-            20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 20, 0,
+            21, 22, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -813,18 +823,19 @@
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 23, 0, 0, 0
+            0, 0, 0, 0, 0, 24, 0, 0, 0
         ],
         r3: &[
             0x0000000000000000, 0xffffffff00000000, 0x00000000000020bf, 0x003fffffffffffff,
-            0x5555555555555555, 0x5555555540155555, 0xff00ff003f00ff00, 0x0000ff00aa003f00,
-            0x0f00000000000000, 0x0f001f000f000f00, 0xc00f3d503e273884, 0x0000ffff00000020,
-            0x0000000000000008, 0xffc0000000000000, 0x000000000000ffff, 0x00007fffffffffff,
-            0xc025ea9d00000000, 0x0004280555555555, 0x0000155555555555, 0x0000000005555555,
-            0x5554555400000000, 0x6a00555555555555, 0x005f7d5555452855, 0x07fffffe00000000
+            0xe7ffffffffff0000, 0x5555555555555555, 0x5555555540155555, 0xff00ff003f00ff00,
+            0x0000ff00aa003f00, 0x0f00000000000000, 0x0f001f000f000f00, 0xc00f3d503e273884,
+            0x0000ffff00000020, 0x0000000000000008, 0xffc0000000000000, 0x000000000000ffff,
+            0x00007fffffffffff, 0xc025ea9d00000000, 0x0004280555555555, 0x0000155555555555,
+            0x0000000005555555, 0x5554555400000000, 0x6a00555555555555, 0x015f7d5555452855,
+            0x07fffffe00000000
         ],
         r4: [
-            0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 4, 5, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -842,22 +853,24 @@
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+            21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 24, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
         ],
         r6: &[
             0x0000000000000000, 0x000000ffffffffff, 0xffff000000000000, 0x00000000000fffff,
-            0x0007ffffffffffff, 0xffffffff00000000, 0xfff0000003ffffff, 0xffffff0000003fff,
-            0x003fde64d0000003, 0x000003ffffff0000, 0x7b0000001fdfe7b0, 0xfffff0000001fc5f,
-            0x03ffffff0000003f, 0x00003ffffff00000, 0xf0000003ffffff00, 0xffff0000003fffff,
-            0xffffff00000003ff, 0x07fffffc00000001, 0x001ffffff0000000, 0x00007fffffc00000,
-            0x000001ffffff0000, 0x0000000000000400, 0x00000003ffffffff, 0xffff03ffffff03ff,
-            0x00000000000003ff
+            0x0007ffffffffffff, 0xffffffff00000000, 0x00000000ffffffff, 0xfff0000003ffffff,
+            0xffffff0000003fff, 0x003fde64d0000003, 0x000003ffffff0000, 0x7b0000001fdfe7b0,
+            0xfffff0000001fc5f, 0x03ffffff0000003f, 0x00003ffffff00000, 0xf0000003ffffff00,
+            0xffff0000003fffff, 0xffffff00000003ff, 0x07fffffc00000001, 0x001ffffff0000000,
+            0x00007fffffc00000, 0x000001ffffff0000, 0x0000000000000400, 0x00000003ffffffff,
+            0xffff03ffffff03ff, 0x00000000000003ff
         ],
     };
 
@@ -872,19 +885,19 @@
             0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x0000501f0003ffc3,
             0xffffffffffffffff, 0xb8dfffffffffffff, 0xfffffffbffffd7c0, 0xffbfffffffffffff,
             0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffffcfb, 0xffffffffffffffff,
-            0xfffeffffffffffff, 0xfffffffe027fffff, 0xbffffffffffe00ff, 0x000707ffffff00b6,
+            0xfffeffffffffffff, 0xffffffff027fffff, 0xbffffffffffe01ff, 0x000787ffffff00b6,
             0xffffffff07ff0000, 0xffffc3ffffffffff, 0xffffffffffffffff, 0x9ffffdff9fefffff,
-            0xffffffffffff0000, 0xffffffffffffe7ff, 0x0003ffffffffffff, 0x043fffffffffffff
+            0xffffffffffff0000, 0xffffffffffffe7ff, 0x0003ffffffffffff, 0x243fffffffffffff
         ],
         r2: [
             0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
             24, 25, 26, 27, 28, 29, 30, 31, 4, 32, 33, 34, 4, 4, 4, 4, 4, 35, 36, 37, 38, 39, 40,
             41, 42, 4, 4, 4, 4, 4, 4, 4, 4, 43, 44, 45, 46, 47, 4, 48, 49, 50, 51, 52, 53, 54, 55,
-            56, 57, 58, 59, 60, 4, 61, 4, 62, 50, 63, 64, 65, 4, 4, 4, 66, 4, 4, 4, 4, 67, 68, 69,
-            70, 71, 72, 73, 74, 75, 76, 64, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
+            56, 57, 58, 59, 60, 4, 61, 4, 62, 63, 64, 65, 66, 4, 4, 4, 67, 4, 4, 4, 4, 68, 69, 70,
+            71, 72, 73, 74, 75, 76, 77, 78, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
             60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
-            60, 60, 60, 60, 60, 77, 78, 4, 79, 80, 81, 82, 83, 60, 60, 60, 60, 60, 60, 60, 60, 84,
-            42, 85, 86, 87, 4, 88, 89, 60, 60, 60, 60, 60, 60, 60, 60, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            60, 60, 60, 60, 60, 79, 80, 4, 81, 82, 83, 84, 85, 60, 60, 60, 60, 60, 60, 60, 60, 86,
+            42, 87, 88, 89, 4, 90, 91, 60, 60, 60, 60, 60, 60, 60, 60, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
@@ -899,30 +912,30 @@
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 90, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 91, 92, 4, 4, 4, 4, 93, 94, 4, 95, 96, 4, 97, 98, 99, 62, 4, 100, 101,
-            102, 4, 103, 104, 105, 4, 106, 107, 108, 4, 109, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 92, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 93, 94, 4, 4, 4, 4, 95, 96, 4, 97, 98, 4, 99, 100, 101, 62, 4, 102, 103,
+            104, 4, 105, 106, 107, 4, 108, 109, 110, 4, 111, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 110, 111, 60, 60, 60, 60, 60, 60, 60,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 112, 113, 60, 60, 60, 60, 60, 60, 60,
             60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
             60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
             60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
             60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
             60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
-            60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 4, 4, 4, 4, 4, 101, 4, 112,
-            113, 114, 95, 115, 4, 116, 4, 4, 117, 118, 119, 120, 121, 122, 4, 123, 124, 125, 126,
-            127
+            60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 4, 4, 4, 4, 4, 103, 4, 114,
+            115, 116, 97, 117, 4, 118, 4, 4, 119, 120, 121, 122, 123, 124, 4, 125, 126, 127, 128,
+            129
         ],
         r3: &[
-            0x00003fffffffffff, 0x000007ff0fffffff, 0x3fdfffff00000000, 0xfffffffbfff00000,
-            0xffffffffffffffff, 0xfffeffcfffffffff, 0xf3c5fdfffff99fef, 0x1003ffcfb080799f,
+            0x00003fffffffffff, 0x000007ff0fffffff, 0x3fdfffff00000000, 0xfffffffbfff80000,
+            0xffffffffffffffff, 0xfffeffcfffffffff, 0xf3c5fdfffff99fef, 0x5003ffcfb080799f,
             0xd36dfdfffff987ee, 0x003fffc05e023987, 0xf3edfdfffffbbfee, 0xfe00ffcf00013bbf,
             0xf3edfdfffff99fee, 0x0002ffcfb0c0399f, 0xc3ffc718d63dc7ec, 0x0000ffc000813dc7,
-            0xe3fffdfffffddfef, 0x0000ffcf07603ddf, 0xf3effdfffffddfef, 0x0006ffcf40603ddf,
+            0xe3fffdfffffddfff, 0x0000ffcf07603ddf, 0xf3effdfffffddfef, 0x0006ffcf40603ddf,
             0xfffffffffffddfef, 0xfc00ffcf80f07ddf, 0x2ffbfffffc7fffec, 0x000cffc0ff5f847f,
             0x07fffffffffffffe, 0x0000000003ff7fff, 0x3bffecaefef02596, 0x00000000f3ff3f5f,
             0xc2a003ff03000001, 0xfffe1ffffffffeff, 0x1ffffffffeffffdf, 0x0000000000000040,
@@ -930,26 +943,27 @@
             0x7f3dffffffff3dff, 0xffffffffff7fff3d, 0xffffffffff3dffff, 0x0003fe00e7ffffff,
             0xffffffff0000ffff, 0x3f3fffffffffffff, 0xfffffffffffffffe, 0xffff9fffffffffff,
             0xffffffff07fffffe, 0x01ffc7ffffffffff, 0x001fffff001fdfff, 0x000ddfff000fffff,
-            0x000003ff308fffff, 0xffffffff03ff3800, 0x00ffffffffffffff, 0xffff07ffffffffff,
+            0x000003ff308fffff, 0xffffffff03ff3800, 0x01ffffffffffffff, 0xffff07ffffffffff,
             0x003fffffffffffff, 0x0fff0fff7fffffff, 0x001f3fffffffffc0, 0xffff0fffffffffff,
             0x0000000007ff03ff, 0xffffffff0fffffff, 0x9fffffff7fffffff, 0x3fff008003ff03ff,
-            0x0000000000000000, 0x000ff80003ff0fff, 0x000fffffffffffff, 0x3fffffffffffe3ff,
-            0x00000000000001ff, 0x03fffffffff70000, 0xfbffffffffffffff, 0xffffffff3f3fffff,
-            0x3fffffffaaff3f3f, 0x5fdfffffffffffff, 0x1fdc1fff0fcf1fdc, 0x8000000000000000,
-            0x8002000000100001, 0x000000001fff0000, 0x0001ffe21fff0000, 0xf3fffd503f2ffc84,
-            0xffffffff000043e0, 0xffff7fffffffffff, 0xffffffff7fffffff, 0x000ff81fffffffff,
-            0xffff20bfffffffff, 0x800080ffffffffff, 0x7f7f7f7f007fffff, 0xffffffff7f7f7f7f,
-            0x1f3efffe000000e0, 0xfffffffee67fffff, 0xf7ffffffffffffff, 0xfffe7fffffffffe0,
-            0x07ffffff00007fff, 0xffff000000000000, 0x000007ffffffffff, 0x0000000000001fff,
-            0x3fffffffffff0000, 0x00000fffffff1fff, 0xbff0ffffffffffff, 0x0003ffffffffffff,
-            0xfffffffcff800000, 0x00ff7ffffffff9ff, 0xff80000000000000, 0x000000ffffffffff,
-            0x28ffffff03ff003f, 0xffff3fffffffffff, 0x1fffffff000fffff, 0x7fffffff03ff8001,
-            0x007fffffffffffff, 0xfc7fffff03ff3fff, 0x007cffff38000007, 0xffff7f7f007e7e7e,
-            0xffff003ff7ffffff, 0x03ff37ffffffffff, 0xffff000fffffffff, 0x0ffffffffffff87f,
-            0x0000000003ffffff, 0x5f7ffdffe0f8007f, 0xffffffffffffffdb, 0xfffffffffff80000,
-            0xfffffff03fffffff, 0x3fffffffffffffff, 0xffffffffffff0000, 0xfffffffffffcffff,
-            0x03ff0000000000ff, 0x0018ffff0000ffff, 0xaa8a00000000e000, 0x1fffffffffffffff,
-            0x87fffffe03ff0000, 0xffffffc007fffffe, 0x7fffffffffffffff, 0x000000001cfcfcfc
+            0x0000000000000000, 0x000ff80003ff0fff, 0x000fffffffffffff, 0x00ffffffffffffff,
+            0x3fffffffffffe3ff, 0xe7ffffffffff01ff, 0x03fffffffff70000, 0xfbffffffffffffff,
+            0xffffffff3f3fffff, 0x3fffffffaaff3f3f, 0x5fdfffffffffffff, 0x1fdc1fff0fcf1fdc,
+            0x8000000000000000, 0x8002000000100001, 0x000000001fff0000, 0x0001ffe21fff0000,
+            0xf3fffd503f2ffc84, 0xffffffff000043e0, 0x00000000000001ff, 0xffff7fffffffffff,
+            0xffffffff7fffffff, 0x000ff81fffffffff, 0xffff20bfffffffff, 0x800080ffffffffff,
+            0x7f7f7f7f007fffff, 0xffffffff7f7f7f7f, 0x1f3efffe000000e0, 0xfffffffee67fffff,
+            0xf7ffffffffffffff, 0xfffeffffffffffe0, 0x07ffffff00007fff, 0xffff000000000000,
+            0x0000ffffffffffff, 0x0000000000001fff, 0x3fffffffffff0000, 0x00000fffffff1fff,
+            0xbff0ffffffffffff, 0x0003ffffffffffff, 0xfffffffcff800000, 0x03fffffffffff9ff,
+            0xff80000000000000, 0x000000ffffffffff, 0xe8ffffff03ff003f, 0xffff3fffffffffff,
+            0x1fffffff000fffff, 0x7fffffff03ff8001, 0x007fffffffffffff, 0xfc7fffff03ff3fff,
+            0x007cffff38000007, 0xffff7f7f007e7e7e, 0xffff003ff7ffffff, 0x03ff37ffffffffff,
+            0xffff000fffffffff, 0x0ffffffffffff87f, 0x0000000003ffffff, 0x5f7ffdffe0f8007f,
+            0xffffffffffffffdb, 0xfffffffffff80000, 0xfffffff03fffffff, 0x3fffffffffffffff,
+            0xffffffffffff0000, 0xfffffffffffcffff, 0x03ff0000000000ff, 0x0018ffff0000ffff,
+            0xaa8a00000000e000, 0x1fffffffffffffff, 0x87fffffe03ff0000, 0xffffffc007fffffe,
+            0x7fffffffffffffff, 0x000000001cfcfcfc
         ],
         r4: [
             0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 10, 11, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 13,
@@ -965,45 +979,45 @@
         r5: &[
             0, 1, 2, 3, 4, 5, 4, 6, 4, 4, 7, 8, 9, 10, 11, 12, 2, 2, 13, 14, 15, 16, 4, 4, 2, 2, 2,
             2, 17, 18, 4, 4, 19, 20, 21, 22, 23, 4, 24, 4, 25, 26, 27, 28, 29, 30, 31, 4, 2, 32, 33,
-            33, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 34, 3, 35, 36, 37, 2, 38, 39, 4, 40, 41, 42,
-            43, 4, 4, 2, 44, 2, 45, 4, 4, 46, 47, 2, 48, 49, 50, 51, 4, 4, 4, 4, 4, 52, 53, 4, 4, 4,
-            4, 54, 55, 56, 57, 4, 4, 4, 4, 58, 59, 60, 4, 61, 62, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 63, 4, 2, 64, 2, 2, 2, 65, 4, 4, 4, 4, 4, 4, 4,
+            33, 34, 4, 4, 4, 4, 4, 4, 4, 35, 36, 4, 4, 2, 37, 3, 38, 39, 40, 2, 41, 42, 4, 43, 44,
+            45, 46, 4, 4, 2, 47, 2, 48, 4, 4, 49, 50, 2, 51, 52, 53, 54, 4, 4, 4, 3, 4, 55, 56, 4,
+            4, 4, 4, 57, 58, 59, 60, 4, 4, 4, 4, 61, 62, 63, 4, 64, 65, 66, 4, 4, 4, 4, 67, 4, 4, 4,
+            4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 68, 4, 2, 69, 2, 2, 2, 70, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 64, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 66, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 71, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2,
-            2, 2, 2, 2, 2, 2, 57, 67, 4, 68, 17, 69, 70, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2,
-            71, 72, 73, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            2, 2, 2, 2, 2, 2, 2, 2, 60, 72, 4, 73, 17, 74, 75, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4,
+            4, 2, 76, 77, 78, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 74, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 21, 75, 2, 2, 2, 2, 2, 76,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 79, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 21, 80, 2, 2, 2, 2, 2,
+            81, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 2, 82, 83, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            84, 85, 4, 4, 86, 4, 4, 4, 4, 4, 4, 2, 87, 88, 89, 90, 91, 2, 2, 2, 2, 92, 93, 94, 95,
+            96, 97, 4, 4, 4, 4, 4, 4, 4, 4, 98, 99, 100, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 101, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 102, 2, 103, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 104, 105, 106, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 107, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 11, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 108,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 109, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 2, 77, 78, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            79, 80, 4, 4, 81, 4, 4, 4, 4, 4, 4, 2, 82, 83, 84, 85, 86, 2, 2, 2, 2, 87, 88, 89, 90,
-            91, 92, 4, 4, 4, 4, 4, 4, 4, 4, 93, 94, 95, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 96, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 97, 2, 44, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 98, 99, 100, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 101, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 11, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 102, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 103, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 110, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 111, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 104, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 105, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
         ],
         r6: &[
             0xb7ffff7fffffefff, 0x000000003fff3fff, 0xffffffffffffffff, 0x07ffffffffffffff,
@@ -1012,27 +1026,28 @@
             0x00000000003eff0f, 0xffff03ff3fffffff, 0x0fffffffff0fffff, 0xffff00ffffffffff,
             0x0000000fffffffff, 0x007fffffffffffff, 0x000000ff003fffff, 0x91bffffffffffd3f,
             0x007fffff003fffff, 0x000000007fffffff, 0x0037ffff00000000, 0x03ffffff003fffff,
-            0xc0ffffffffffffff, 0x870ffffffeeff06f, 0x1fffffff00000000, 0x000000001fffffff,
+            0xc0ffffffffffffff, 0x873ffffffeeff06f, 0x1fffffff00000000, 0x000000001fffffff,
             0x0000007ffffffeff, 0x003fffffffffffff, 0x0007ffff003fffff, 0x000000000003ffff,
-            0x00000000000001ff, 0x0007ffffffffffff, 0x8000ffc00000007f, 0x03ff01ffffff0000,
-            0xffdfffffffffffff, 0x004fffffffff0000, 0x0000000017ff1c1f, 0x40fffffffffbffff,
-            0xffff01ffbfffbd7f, 0x03ff07ffffffffff, 0xf3edfdfffff99fef, 0x001f1fcfe081399f,
-            0x0000000003ff07ff, 0x0000000003ff00bf, 0xff3fffffffffffff, 0x000000003f000001,
-            0x0000000003ff0011, 0x00ffffffffffffff, 0x00000000000003ff, 0x03ff0fffe3ffffff,
-            0xffffffff00000000, 0x800003ffffffffff, 0x7fffffffffffffff, 0xffffffffffff0080,
-            0x0000000003ffffcf, 0x01ffffffffffffff, 0xff7ffffffffffdff, 0xfffc000003ff0001,
-            0x007ffefffffcffff, 0xb47ffffffffffb7f, 0x0000000003ff00ff, 0x0000000003ffffff,
-            0x00007fffffffffff, 0x000000000000000f, 0x000000000000007f, 0x000003ff7fffffff,
-            0x001f3fffffff0000, 0xe0fffff803ff000f, 0x000000000000ffff, 0x7fffffffffff001f,
-            0x00000000ffff8000, 0x0000000300000000, 0x00001fffffffffff, 0xffff000000000000,
-            0x0fffffffffffffff, 0x1fff07ffffffffff, 0x0000000063ff01ff, 0xf807e3e000000000,
-            0x00003c0000000fe7, 0x000000000000001c, 0xffffffffffdfffff, 0xebffde64dfffffff,
-            0xffffffffffffffef, 0x7bffffffdfdfe7bf, 0xfffffffffffdfc5f, 0xffffff3fffffffff,
-            0xf7fffffff7fffffd, 0xffdfffffffdfffff, 0xffff7fffffff7fff, 0xfffffdfffffffdff,
-            0xffffffffffffcff7, 0xf87fffffffffffff, 0x00201fffffffffff, 0x0000fffef8000010,
-            0x000007dbf9ffff7f, 0x00000000007f001f, 0x0af7fe96ffffffef, 0x5ef7f796aa96ea84,
-            0x0ffffbee0ffffbff, 0x00000000007fffff, 0xffff0003ffffffff, 0x00000001ffffffff,
-            0x000000003fffffff, 0x0000ffffffffffff
+            0x00000000000001ff, 0x0007ffffffffffff, 0x03ff00ffffffffff, 0xffff00801fffffff,
+            0x000000000001ffff, 0x8000ffc00000007f, 0x03ff01ffffff0000, 0xffdfffffffffffff,
+            0x004fffffffff0070, 0x0000000017ff1e1f, 0x40fffffffffbffff, 0xffff01ffbfffbd7f,
+            0x03ff07ffffffffff, 0xfbedfdfffff99fef, 0x001f1fcfe081399f, 0x0000000043ff07ff,
+            0x0000000003ff00bf, 0xff3fffffffffffff, 0x000000003f000001, 0x0000000003ff0011,
+            0x00ffffffffffffff, 0x00000000000003ff, 0x03ff0fffe7ffffff, 0xffffffff00000000,
+            0x800003ffffffffff, 0x7fffffffffffffff, 0xffffffffffff0080, 0x0000000023ffffcf,
+            0x01ffffffffffffff, 0xff7ffffffffffdff, 0xfffc000003ff0001, 0x007ffefffffcffff,
+            0xb47ffffffffffb7f, 0xfffffdbf03ff00ff, 0x000003ff01fb7fff, 0x007fffff00000000,
+            0x0000000003ffffff, 0x00007fffffffffff, 0x000000000000000f, 0x000000000000007f,
+            0x000003ff7fffffff, 0x001f3fffffff0000, 0xe0fffff803ff000f, 0x000000000000ffff,
+            0x7fffffffffff001f, 0x00000000ffff8000, 0x0000000300000000, 0x0003ffffffffffff,
+            0xffff000000000000, 0x0fffffffffffffff, 0x1fff07ffffffffff, 0x0000000063ff01ff,
+            0xf807e3e000000000, 0x00003c0000000fe7, 0x000000000000001c, 0xffffffffffdfffff,
+            0xebffde64dfffffff, 0xffffffffffffffef, 0x7bffffffdfdfe7bf, 0xfffffffffffdfc5f,
+            0xffffff3fffffffff, 0xf7fffffff7fffffd, 0xffdfffffffdfffff, 0xffff7fffffff7fff,
+            0xfffffdfffffffdff, 0xffffffffffffcff7, 0xf87fffffffffffff, 0x00201fffffffffff,
+            0x0000fffef8000010, 0x000007dbf9ffff7f, 0x00000000007f001f, 0x0000000003ff07ff,
+            0x0af7fe96ffffffef, 0x5ef7f796aa96ea84, 0x0ffffbee0ffffbff, 0x00000000007fffff,
+            0xffff0003ffffffff, 0x00000001ffffffff, 0x000000003fffffff, 0x0000ffffffffffff
         ],
     };
 
@@ -1047,7 +1062,7 @@
             0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x0000501f0003ffc3,
             0x0000000000000000, 0xb8df000000000000, 0xfffffffbffffd740, 0xffbfffffffffffff,
             0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffffc03, 0xffffffffffffffff,
-            0xfffeffffffffffff, 0xfffffffe027fffff, 0x00000000000000ff, 0x000707ffffff0000,
+            0xfffeffffffffffff, 0xffffffff027fffff, 0x00000000000001ff, 0x000787ffffff0000,
             0xffffffff00000000, 0xfffec000000007ff, 0xffffffffffffffff, 0x9c00c060002fffff,
             0x0000fffffffd0000, 0xffffffffffffe000, 0x0002003fffffffff, 0x043007fffffffc00
         ],
@@ -1056,9 +1071,9 @@
             24, 23, 25, 26, 27, 28, 29, 3, 30, 31, 32, 33, 34, 34, 34, 34, 34, 35, 36, 37, 38, 39,
             40, 41, 42, 34, 34, 34, 34, 34, 34, 34, 34, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
             54, 55, 56, 57, 58, 59, 60, 3, 61, 62, 63, 64, 65, 66, 67, 68, 34, 34, 34, 3, 34, 34,
-            34, 34, 69, 70, 71, 72, 3, 73, 74, 3, 75, 76, 67, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-            3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 77,
-            78, 34, 79, 80, 81, 82, 83, 3, 3, 3, 3, 3, 3, 3, 3, 84, 42, 85, 86, 87, 34, 88, 89, 3,
+            34, 34, 69, 70, 71, 72, 3, 73, 74, 3, 75, 76, 77, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+            3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 78,
+            79, 34, 80, 81, 82, 83, 84, 3, 3, 3, 3, 3, 3, 3, 3, 85, 42, 86, 87, 88, 34, 89, 90, 3,
             3, 3, 3, 3, 3, 3, 3, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
             34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
             34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
@@ -1078,9 +1093,9 @@
             34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
             34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
             34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 90, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 91, 92, 34, 34, 34, 34, 93,
-            94, 95, 96, 97, 34, 98, 99, 100, 48, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
+            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 91, 34, 34, 34,
+            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 92, 93, 34, 34, 34, 34, 94,
+            95, 96, 91, 97, 34, 98, 99, 100, 48, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
             111, 112, 34, 113, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
             34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
             34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
@@ -1110,20 +1125,20 @@
             0x7f3dffffffff3dff, 0xffffffffff7fff3d, 0xffffffffff3dffff, 0x0000000007ffffff,
             0xffffffff0000ffff, 0x3f3fffffffffffff, 0xfffffffffffffffe, 0xffff9fffffffffff,
             0xffffffff07fffffe, 0x01ffc7ffffffffff, 0x0003ffff0003dfff, 0x0001dfff0003ffff,
-            0x000fffffffffffff, 0x0000000010800000, 0xffffffff00000000, 0x00ffffffffffffff,
+            0x000fffffffffffff, 0x0000000010800000, 0xffffffff00000000, 0x01ffffffffffffff,
             0xffff05ffffffffff, 0x003fffffffffffff, 0x000000007fffffff, 0x001f3fffffff0000,
             0xffff0fffffffffff, 0x00000000000003ff, 0xffffffff007fffff, 0x00000000001fffff,
             0x0000008000000000, 0x000fffffffffffe0, 0x0000000000000fe0, 0xfc00c001fffffff8,
-            0x0000003fffffffff, 0x0000000fffffffff, 0x3ffffffffc00e000, 0x00000000000001ff,
+            0x0000003fffffffff, 0x0000000fffffffff, 0x3ffffffffc00e000, 0xe7ffffffffff01ff,
             0x0063de0000000000, 0xffffffff3f3fffff, 0x3fffffffaaff3f3f, 0x5fdfffffffffffff,
             0x1fdc1fff0fcf1fdc, 0x8002000000000000, 0x000000001fff0000, 0xf3fffd503f2ffc84,
-            0xffffffff000043e0, 0xffff7fffffffffff, 0xffffffff7fffffff, 0x000c781fffffffff,
-            0xffff20bfffffffff, 0x000080ffffffffff, 0x7f7f7f7f007fffff, 0x000000007f7f7f7f,
-            0x1f3e03fe000000e0, 0xfffffffee07fffff, 0xf7ffffffffffffff, 0xfffe7fffffffffe0,
-            0x07ffffff00007fff, 0xffff000000000000, 0x000007ffffffffff, 0x0000000000001fff,
-            0x3fffffffffff0000, 0x00000c00ffff1fff, 0x80007fffffffffff, 0xffffffff3fffffff,
-            0x0000ffffffffffff, 0xfffffffcff800000, 0x00ff7ffffffff9ff, 0xff80000000000000,
-            0x00000007fffff7bb, 0x000ffffffffffffc, 0x28fc000000000000, 0xffff003ffffffc00,
+            0xffffffff000043e0, 0x00000000000001ff, 0xffff7fffffffffff, 0xffffffff7fffffff,
+            0x000c781fffffffff, 0xffff20bfffffffff, 0x000080ffffffffff, 0x7f7f7f7f007fffff,
+            0x000000007f7f7f7f, 0x1f3e03fe000000e0, 0xfffffffee07fffff, 0xf7ffffffffffffff,
+            0xfffeffffffffffe0, 0x07ffffff00007fff, 0xffff000000000000, 0x0000ffffffffffff,
+            0x0000000000001fff, 0x3fffffffffff0000, 0x00000c00ffff1fff, 0x80007fffffffffff,
+            0xffffffff3fffffff, 0xfffffffcff800000, 0x03fffffffffff9ff, 0xff80000000000000,
+            0x00000007fffff7bb, 0x000ffffffffffffc, 0x68fc000000000000, 0xffff003ffffffc00,
             0x1fffffff0000007f, 0x0007fffffffffff0, 0x7c00ffdf00008000, 0x000001ffffffffff,
             0xc47fffff00000ff7, 0x3e62ffffffffffff, 0x001c07ff38000005, 0xffff7f7f007e7e7e,
             0xffff003ff7ffffff, 0x00000007ffffffff, 0xffff000fffffffff, 0x0ffffffffffff87f,
@@ -1147,42 +1162,42 @@
         r5: &[
             0, 1, 2, 3, 4, 5, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 2, 2, 12, 13, 14, 15, 4, 4, 2, 2, 2,
             2, 16, 17, 4, 4, 18, 19, 20, 21, 22, 4, 23, 4, 24, 25, 26, 27, 28, 29, 30, 4, 2, 31, 32,
-            32, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 33, 4, 34, 35, 36, 37, 38, 39, 40, 4, 41, 20,
-            42, 43, 4, 4, 5, 44, 45, 46, 4, 4, 47, 48, 45, 49, 50, 4, 51, 4, 4, 4, 4, 4, 52, 53, 4,
-            4, 4, 4, 54, 55, 56, 57, 4, 4, 4, 4, 58, 59, 60, 4, 61, 62, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 51, 4, 2, 47, 2, 2, 2, 63, 4, 4, 4, 4, 4,
+            32, 15, 4, 4, 4, 4, 4, 4, 4, 33, 34, 4, 4, 35, 4, 36, 37, 38, 39, 40, 41, 42, 4, 43, 20,
+            44, 45, 4, 4, 5, 46, 47, 48, 4, 4, 49, 50, 47, 51, 52, 4, 53, 4, 4, 4, 54, 4, 55, 56, 4,
+            4, 4, 4, 57, 58, 59, 60, 4, 4, 4, 4, 61, 62, 63, 4, 64, 65, 66, 4, 4, 4, 4, 67, 4, 4, 4,
+            4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 68, 4, 2, 49, 2, 2, 2, 69, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 47, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 49, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 64, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 70, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            2, 2, 2, 2, 2, 2, 2, 2, 57, 20, 4, 65, 45, 66, 60, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 2, 67, 68, 69, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 60, 20, 4, 71, 47, 72, 63, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4,
+            4, 2, 73, 74, 75, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 70, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 32, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 20, 71, 2, 2, 2, 2, 2,
-            72, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 2, 73, 74, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 75, 76, 77, 78, 79, 2, 2, 2, 2, 80, 81, 82, 83, 84,
-            85, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 76, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 32, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 20, 77, 2, 2, 2, 2, 2,
+            78, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 2, 79, 80, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 81, 82, 83, 84, 85, 2, 2, 2, 2, 86, 87, 88, 89, 90,
+            91, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 86, 2, 63, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 87, 88, 89, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 90, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 92, 2, 69, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 93, 94, 95, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 96, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 91, 2, 2, 2, 2, 2,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 97, 2, 2, 2, 2, 2,
             2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 92, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 98, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 93, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+            4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 99, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
             4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
         ],
         r6: &[
@@ -1192,24 +1207,25 @@
             0xffff00003fffffff, 0x0fffffffff0fffff, 0xffff00ffffffffff, 0x0000000fffffffff,
             0x007fffffffffffff, 0x000000ff003fffff, 0x91bffffffffffd3f, 0x007fffff003fffff,
             0x000000007fffffff, 0x0037ffff00000000, 0x03ffffff003fffff, 0xc0ffffffffffffff,
-            0x000ffffffeef0001, 0x1fffffff00000000, 0x000000001fffffff, 0x0000001ffffffeff,
+            0x003ffffffeef0001, 0x1fffffff00000000, 0x000000001fffffff, 0x0000001ffffffeff,
             0x003fffffffffffff, 0x0007ffff003fffff, 0x000000000003ffff, 0x00000000000001ff,
-            0x0007ffffffffffff, 0x00fffffffffffff8, 0x0000fffffffffff8, 0x000001ffffff0000,
-            0x0000007ffffffff8, 0x0047ffffffff0000, 0x0007fffffffffff8, 0x000000001400001e,
-            0x00000ffffffbffff, 0xffff01ffbfffbd7f, 0x23edfdfffff99fe0, 0x00000003e0010000,
-            0x0000000000000780, 0x0000ffffffffffff, 0x00000000000000b0, 0x00007fffffffffff,
-            0x000000000f000000, 0x0000000000000010, 0x000007ffffffffff, 0x0000000003ffffff,
-            0xffffffff00000000, 0x80000000ffffffff, 0x0407fffffffff801, 0xfffffffff0010000,
-            0x00000000000003cf, 0x01ffffffffffffff, 0x00007ffffffffdff, 0xfffc000000000001,
-            0x000000000000ffff, 0x0001fffffffffb7f, 0x0000000000000040, 0x000000000000000f,
-            0x000000000000007f, 0x00003fffffff0000, 0xe0fffff80000000f, 0x000000000001001f,
-            0x00000000fff80000, 0x0000000300000000, 0x00001fffffffffff, 0xffff000000000000,
-            0x0fffffffffffffff, 0x1fff07ffffffffff, 0x0000000003ff01ff, 0xffffffffffdfffff,
-            0xebffde64dfffffff, 0xffffffffffffffef, 0x7bffffffdfdfe7bf, 0xfffffffffffdfc5f,
-            0xffffff3fffffffff, 0xf7fffffff7fffffd, 0xffdfffffffdfffff, 0xffff7fffffff7fff,
-            0xfffffdfffffffdff, 0x0000000000000ff7, 0x000000000000001f, 0x0af7fe96ffffffef,
-            0x5ef7f796aa96ea84, 0x0ffffbee0ffffbff, 0x00000000007fffff, 0xffff0003ffffffff,
-            0x00000001ffffffff, 0x000000003fffffff
+            0x0007ffffffffffff, 0xffff00801fffffff, 0x000000000000003f, 0x00fffffffffffff8,
+            0x0000fffffffffff8, 0x000001ffffff0000, 0x0000007ffffffff8, 0x0047ffffffff0010,
+            0x0007fffffffffff8, 0x000000001400001e, 0x00000ffffffbffff, 0xffff01ffbfffbd7f,
+            0x23edfdfffff99fe0, 0x00000003e0010000, 0x0000000000000780, 0x0000ffffffffffff,
+            0x00000000000000b0, 0x00007fffffffffff, 0x000000000f000000, 0x0000000000000010,
+            0x000007ffffffffff, 0x0000000007ffffff, 0x00000fffffffffff, 0xffffffff00000000,
+            0x80000000ffffffff, 0x0407fffffffff801, 0xfffffffff0010000, 0x00000000200003cf,
+            0x01ffffffffffffff, 0x00007ffffffffdff, 0xfffc000000000001, 0x000000000000ffff,
+            0x0001fffffffffb7f, 0xfffffdbf00000040, 0x00000000010003ff, 0x0007ffff00000000,
+            0x0000000003ffffff, 0x000000000000000f, 0x000000000000007f, 0x00003fffffff0000,
+            0xe0fffff80000000f, 0x000000000001001f, 0x00000000fff80000, 0x0000000300000000,
+            0x0003ffffffffffff, 0xffff000000000000, 0x0fffffffffffffff, 0x1fff07ffffffffff,
+            0x0000000003ff01ff, 0xffffffffffdfffff, 0xebffde64dfffffff, 0xffffffffffffffef,
+            0x7bffffffdfdfe7bf, 0xfffffffffffdfc5f, 0xffffff3fffffffff, 0xf7fffffff7fffffd,
+            0xffdfffffffdfffff, 0xffff7fffffff7fff, 0xfffffdfffffffdff, 0x0000000000000ff7,
+            0x000000000000001f, 0x0af7fe96ffffffef, 0x5ef7f796aa96ea84, 0x0ffffbee0ffffbff,
+            0x00000000007fffff, 0xffff0003ffffffff, 0x00000001ffffffff, 0x000000003fffffff
         ],
     };
 
@@ -1534,332 +1550,369 @@
         ('\u{13ee}', ['\u{abbe}', '\0', '\0']), ('\u{13ef}', ['\u{abbf}', '\0', '\0']), ('\u{13f0}',
         ['\u{13f8}', '\0', '\0']), ('\u{13f1}', ['\u{13f9}', '\0', '\0']), ('\u{13f2}', ['\u{13fa}',
         '\0', '\0']), ('\u{13f3}', ['\u{13fb}', '\0', '\0']), ('\u{13f4}', ['\u{13fc}', '\0',
-        '\0']), ('\u{13f5}', ['\u{13fd}', '\0', '\0']), ('\u{1e00}', ['\u{1e01}', '\0', '\0']),
-        ('\u{1e02}', ['\u{1e03}', '\0', '\0']), ('\u{1e04}', ['\u{1e05}', '\0', '\0']), ('\u{1e06}',
-        ['\u{1e07}', '\0', '\0']), ('\u{1e08}', ['\u{1e09}', '\0', '\0']), ('\u{1e0a}', ['\u{1e0b}',
-        '\0', '\0']), ('\u{1e0c}', ['\u{1e0d}', '\0', '\0']), ('\u{1e0e}', ['\u{1e0f}', '\0',
-        '\0']), ('\u{1e10}', ['\u{1e11}', '\0', '\0']), ('\u{1e12}', ['\u{1e13}', '\0', '\0']),
-        ('\u{1e14}', ['\u{1e15}', '\0', '\0']), ('\u{1e16}', ['\u{1e17}', '\0', '\0']), ('\u{1e18}',
-        ['\u{1e19}', '\0', '\0']), ('\u{1e1a}', ['\u{1e1b}', '\0', '\0']), ('\u{1e1c}', ['\u{1e1d}',
-        '\0', '\0']), ('\u{1e1e}', ['\u{1e1f}', '\0', '\0']), ('\u{1e20}', ['\u{1e21}', '\0',
-        '\0']), ('\u{1e22}', ['\u{1e23}', '\0', '\0']), ('\u{1e24}', ['\u{1e25}', '\0', '\0']),
-        ('\u{1e26}', ['\u{1e27}', '\0', '\0']), ('\u{1e28}', ['\u{1e29}', '\0', '\0']), ('\u{1e2a}',
-        ['\u{1e2b}', '\0', '\0']), ('\u{1e2c}', ['\u{1e2d}', '\0', '\0']), ('\u{1e2e}', ['\u{1e2f}',
-        '\0', '\0']), ('\u{1e30}', ['\u{1e31}', '\0', '\0']), ('\u{1e32}', ['\u{1e33}', '\0',
-        '\0']), ('\u{1e34}', ['\u{1e35}', '\0', '\0']), ('\u{1e36}', ['\u{1e37}', '\0', '\0']),
-        ('\u{1e38}', ['\u{1e39}', '\0', '\0']), ('\u{1e3a}', ['\u{1e3b}', '\0', '\0']), ('\u{1e3c}',
-        ['\u{1e3d}', '\0', '\0']), ('\u{1e3e}', ['\u{1e3f}', '\0', '\0']), ('\u{1e40}', ['\u{1e41}',
-        '\0', '\0']), ('\u{1e42}', ['\u{1e43}', '\0', '\0']), ('\u{1e44}', ['\u{1e45}', '\0',
-        '\0']), ('\u{1e46}', ['\u{1e47}', '\0', '\0']), ('\u{1e48}', ['\u{1e49}', '\0', '\0']),
-        ('\u{1e4a}', ['\u{1e4b}', '\0', '\0']), ('\u{1e4c}', ['\u{1e4d}', '\0', '\0']), ('\u{1e4e}',
-        ['\u{1e4f}', '\0', '\0']), ('\u{1e50}', ['\u{1e51}', '\0', '\0']), ('\u{1e52}', ['\u{1e53}',
-        '\0', '\0']), ('\u{1e54}', ['\u{1e55}', '\0', '\0']), ('\u{1e56}', ['\u{1e57}', '\0',
-        '\0']), ('\u{1e58}', ['\u{1e59}', '\0', '\0']), ('\u{1e5a}', ['\u{1e5b}', '\0', '\0']),
-        ('\u{1e5c}', ['\u{1e5d}', '\0', '\0']), ('\u{1e5e}', ['\u{1e5f}', '\0', '\0']), ('\u{1e60}',
-        ['\u{1e61}', '\0', '\0']), ('\u{1e62}', ['\u{1e63}', '\0', '\0']), ('\u{1e64}', ['\u{1e65}',
-        '\0', '\0']), ('\u{1e66}', ['\u{1e67}', '\0', '\0']), ('\u{1e68}', ['\u{1e69}', '\0',
-        '\0']), ('\u{1e6a}', ['\u{1e6b}', '\0', '\0']), ('\u{1e6c}', ['\u{1e6d}', '\0', '\0']),
-        ('\u{1e6e}', ['\u{1e6f}', '\0', '\0']), ('\u{1e70}', ['\u{1e71}', '\0', '\0']), ('\u{1e72}',
-        ['\u{1e73}', '\0', '\0']), ('\u{1e74}', ['\u{1e75}', '\0', '\0']), ('\u{1e76}', ['\u{1e77}',
-        '\0', '\0']), ('\u{1e78}', ['\u{1e79}', '\0', '\0']), ('\u{1e7a}', ['\u{1e7b}', '\0',
-        '\0']), ('\u{1e7c}', ['\u{1e7d}', '\0', '\0']), ('\u{1e7e}', ['\u{1e7f}', '\0', '\0']),
-        ('\u{1e80}', ['\u{1e81}', '\0', '\0']), ('\u{1e82}', ['\u{1e83}', '\0', '\0']), ('\u{1e84}',
-        ['\u{1e85}', '\0', '\0']), ('\u{1e86}', ['\u{1e87}', '\0', '\0']), ('\u{1e88}', ['\u{1e89}',
-        '\0', '\0']), ('\u{1e8a}', ['\u{1e8b}', '\0', '\0']), ('\u{1e8c}', ['\u{1e8d}', '\0',
-        '\0']), ('\u{1e8e}', ['\u{1e8f}', '\0', '\0']), ('\u{1e90}', ['\u{1e91}', '\0', '\0']),
-        ('\u{1e92}', ['\u{1e93}', '\0', '\0']), ('\u{1e94}', ['\u{1e95}', '\0', '\0']), ('\u{1e9e}',
-        ['\u{df}', '\0', '\0']), ('\u{1ea0}', ['\u{1ea1}', '\0', '\0']), ('\u{1ea2}', ['\u{1ea3}',
-        '\0', '\0']), ('\u{1ea4}', ['\u{1ea5}', '\0', '\0']), ('\u{1ea6}', ['\u{1ea7}', '\0',
-        '\0']), ('\u{1ea8}', ['\u{1ea9}', '\0', '\0']), ('\u{1eaa}', ['\u{1eab}', '\0', '\0']),
-        ('\u{1eac}', ['\u{1ead}', '\0', '\0']), ('\u{1eae}', ['\u{1eaf}', '\0', '\0']), ('\u{1eb0}',
-        ['\u{1eb1}', '\0', '\0']), ('\u{1eb2}', ['\u{1eb3}', '\0', '\0']), ('\u{1eb4}', ['\u{1eb5}',
-        '\0', '\0']), ('\u{1eb6}', ['\u{1eb7}', '\0', '\0']), ('\u{1eb8}', ['\u{1eb9}', '\0',
-        '\0']), ('\u{1eba}', ['\u{1ebb}', '\0', '\0']), ('\u{1ebc}', ['\u{1ebd}', '\0', '\0']),
-        ('\u{1ebe}', ['\u{1ebf}', '\0', '\0']), ('\u{1ec0}', ['\u{1ec1}', '\0', '\0']), ('\u{1ec2}',
-        ['\u{1ec3}', '\0', '\0']), ('\u{1ec4}', ['\u{1ec5}', '\0', '\0']), ('\u{1ec6}', ['\u{1ec7}',
-        '\0', '\0']), ('\u{1ec8}', ['\u{1ec9}', '\0', '\0']), ('\u{1eca}', ['\u{1ecb}', '\0',
-        '\0']), ('\u{1ecc}', ['\u{1ecd}', '\0', '\0']), ('\u{1ece}', ['\u{1ecf}', '\0', '\0']),
-        ('\u{1ed0}', ['\u{1ed1}', '\0', '\0']), ('\u{1ed2}', ['\u{1ed3}', '\0', '\0']), ('\u{1ed4}',
-        ['\u{1ed5}', '\0', '\0']), ('\u{1ed6}', ['\u{1ed7}', '\0', '\0']), ('\u{1ed8}', ['\u{1ed9}',
-        '\0', '\0']), ('\u{1eda}', ['\u{1edb}', '\0', '\0']), ('\u{1edc}', ['\u{1edd}', '\0',
-        '\0']), ('\u{1ede}', ['\u{1edf}', '\0', '\0']), ('\u{1ee0}', ['\u{1ee1}', '\0', '\0']),
-        ('\u{1ee2}', ['\u{1ee3}', '\0', '\0']), ('\u{1ee4}', ['\u{1ee5}', '\0', '\0']), ('\u{1ee6}',
-        ['\u{1ee7}', '\0', '\0']), ('\u{1ee8}', ['\u{1ee9}', '\0', '\0']), ('\u{1eea}', ['\u{1eeb}',
-        '\0', '\0']), ('\u{1eec}', ['\u{1eed}', '\0', '\0']), ('\u{1eee}', ['\u{1eef}', '\0',
-        '\0']), ('\u{1ef0}', ['\u{1ef1}', '\0', '\0']), ('\u{1ef2}', ['\u{1ef3}', '\0', '\0']),
-        ('\u{1ef4}', ['\u{1ef5}', '\0', '\0']), ('\u{1ef6}', ['\u{1ef7}', '\0', '\0']), ('\u{1ef8}',
-        ['\u{1ef9}', '\0', '\0']), ('\u{1efa}', ['\u{1efb}', '\0', '\0']), ('\u{1efc}', ['\u{1efd}',
-        '\0', '\0']), ('\u{1efe}', ['\u{1eff}', '\0', '\0']), ('\u{1f08}', ['\u{1f00}', '\0',
-        '\0']), ('\u{1f09}', ['\u{1f01}', '\0', '\0']), ('\u{1f0a}', ['\u{1f02}', '\0', '\0']),
-        ('\u{1f0b}', ['\u{1f03}', '\0', '\0']), ('\u{1f0c}', ['\u{1f04}', '\0', '\0']), ('\u{1f0d}',
-        ['\u{1f05}', '\0', '\0']), ('\u{1f0e}', ['\u{1f06}', '\0', '\0']), ('\u{1f0f}', ['\u{1f07}',
-        '\0', '\0']), ('\u{1f18}', ['\u{1f10}', '\0', '\0']), ('\u{1f19}', ['\u{1f11}', '\0',
-        '\0']), ('\u{1f1a}', ['\u{1f12}', '\0', '\0']), ('\u{1f1b}', ['\u{1f13}', '\0', '\0']),
-        ('\u{1f1c}', ['\u{1f14}', '\0', '\0']), ('\u{1f1d}', ['\u{1f15}', '\0', '\0']), ('\u{1f28}',
-        ['\u{1f20}', '\0', '\0']), ('\u{1f29}', ['\u{1f21}', '\0', '\0']), ('\u{1f2a}', ['\u{1f22}',
-        '\0', '\0']), ('\u{1f2b}', ['\u{1f23}', '\0', '\0']), ('\u{1f2c}', ['\u{1f24}', '\0',
-        '\0']), ('\u{1f2d}', ['\u{1f25}', '\0', '\0']), ('\u{1f2e}', ['\u{1f26}', '\0', '\0']),
-        ('\u{1f2f}', ['\u{1f27}', '\0', '\0']), ('\u{1f38}', ['\u{1f30}', '\0', '\0']), ('\u{1f39}',
-        ['\u{1f31}', '\0', '\0']), ('\u{1f3a}', ['\u{1f32}', '\0', '\0']), ('\u{1f3b}', ['\u{1f33}',
-        '\0', '\0']), ('\u{1f3c}', ['\u{1f34}', '\0', '\0']), ('\u{1f3d}', ['\u{1f35}', '\0',
-        '\0']), ('\u{1f3e}', ['\u{1f36}', '\0', '\0']), ('\u{1f3f}', ['\u{1f37}', '\0', '\0']),
-        ('\u{1f48}', ['\u{1f40}', '\0', '\0']), ('\u{1f49}', ['\u{1f41}', '\0', '\0']), ('\u{1f4a}',
-        ['\u{1f42}', '\0', '\0']), ('\u{1f4b}', ['\u{1f43}', '\0', '\0']), ('\u{1f4c}', ['\u{1f44}',
-        '\0', '\0']), ('\u{1f4d}', ['\u{1f45}', '\0', '\0']), ('\u{1f59}', ['\u{1f51}', '\0',
-        '\0']), ('\u{1f5b}', ['\u{1f53}', '\0', '\0']), ('\u{1f5d}', ['\u{1f55}', '\0', '\0']),
-        ('\u{1f5f}', ['\u{1f57}', '\0', '\0']), ('\u{1f68}', ['\u{1f60}', '\0', '\0']), ('\u{1f69}',
-        ['\u{1f61}', '\0', '\0']), ('\u{1f6a}', ['\u{1f62}', '\0', '\0']), ('\u{1f6b}', ['\u{1f63}',
-        '\0', '\0']), ('\u{1f6c}', ['\u{1f64}', '\0', '\0']), ('\u{1f6d}', ['\u{1f65}', '\0',
-        '\0']), ('\u{1f6e}', ['\u{1f66}', '\0', '\0']), ('\u{1f6f}', ['\u{1f67}', '\0', '\0']),
-        ('\u{1f88}', ['\u{1f80}', '\0', '\0']), ('\u{1f89}', ['\u{1f81}', '\0', '\0']), ('\u{1f8a}',
-        ['\u{1f82}', '\0', '\0']), ('\u{1f8b}', ['\u{1f83}', '\0', '\0']), ('\u{1f8c}', ['\u{1f84}',
-        '\0', '\0']), ('\u{1f8d}', ['\u{1f85}', '\0', '\0']), ('\u{1f8e}', ['\u{1f86}', '\0',
-        '\0']), ('\u{1f8f}', ['\u{1f87}', '\0', '\0']), ('\u{1f98}', ['\u{1f90}', '\0', '\0']),
-        ('\u{1f99}', ['\u{1f91}', '\0', '\0']), ('\u{1f9a}', ['\u{1f92}', '\0', '\0']), ('\u{1f9b}',
-        ['\u{1f93}', '\0', '\0']), ('\u{1f9c}', ['\u{1f94}', '\0', '\0']), ('\u{1f9d}', ['\u{1f95}',
-        '\0', '\0']), ('\u{1f9e}', ['\u{1f96}', '\0', '\0']), ('\u{1f9f}', ['\u{1f97}', '\0',
-        '\0']), ('\u{1fa8}', ['\u{1fa0}', '\0', '\0']), ('\u{1fa9}', ['\u{1fa1}', '\0', '\0']),
-        ('\u{1faa}', ['\u{1fa2}', '\0', '\0']), ('\u{1fab}', ['\u{1fa3}', '\0', '\0']), ('\u{1fac}',
-        ['\u{1fa4}', '\0', '\0']), ('\u{1fad}', ['\u{1fa5}', '\0', '\0']), ('\u{1fae}', ['\u{1fa6}',
-        '\0', '\0']), ('\u{1faf}', ['\u{1fa7}', '\0', '\0']), ('\u{1fb8}', ['\u{1fb0}', '\0',
-        '\0']), ('\u{1fb9}', ['\u{1fb1}', '\0', '\0']), ('\u{1fba}', ['\u{1f70}', '\0', '\0']),
-        ('\u{1fbb}', ['\u{1f71}', '\0', '\0']), ('\u{1fbc}', ['\u{1fb3}', '\0', '\0']), ('\u{1fc8}',
-        ['\u{1f72}', '\0', '\0']), ('\u{1fc9}', ['\u{1f73}', '\0', '\0']), ('\u{1fca}', ['\u{1f74}',
-        '\0', '\0']), ('\u{1fcb}', ['\u{1f75}', '\0', '\0']), ('\u{1fcc}', ['\u{1fc3}', '\0',
-        '\0']), ('\u{1fd8}', ['\u{1fd0}', '\0', '\0']), ('\u{1fd9}', ['\u{1fd1}', '\0', '\0']),
-        ('\u{1fda}', ['\u{1f76}', '\0', '\0']), ('\u{1fdb}', ['\u{1f77}', '\0', '\0']), ('\u{1fe8}',
-        ['\u{1fe0}', '\0', '\0']), ('\u{1fe9}', ['\u{1fe1}', '\0', '\0']), ('\u{1fea}', ['\u{1f7a}',
-        '\0', '\0']), ('\u{1feb}', ['\u{1f7b}', '\0', '\0']), ('\u{1fec}', ['\u{1fe5}', '\0',
-        '\0']), ('\u{1ff8}', ['\u{1f78}', '\0', '\0']), ('\u{1ff9}', ['\u{1f79}', '\0', '\0']),
-        ('\u{1ffa}', ['\u{1f7c}', '\0', '\0']), ('\u{1ffb}', ['\u{1f7d}', '\0', '\0']), ('\u{1ffc}',
-        ['\u{1ff3}', '\0', '\0']), ('\u{2126}', ['\u{3c9}', '\0', '\0']), ('\u{212a}', ['\u{6b}',
-        '\0', '\0']), ('\u{212b}', ['\u{e5}', '\0', '\0']), ('\u{2132}', ['\u{214e}', '\0', '\0']),
-        ('\u{2160}', ['\u{2170}', '\0', '\0']), ('\u{2161}', ['\u{2171}', '\0', '\0']), ('\u{2162}',
-        ['\u{2172}', '\0', '\0']), ('\u{2163}', ['\u{2173}', '\0', '\0']), ('\u{2164}', ['\u{2174}',
-        '\0', '\0']), ('\u{2165}', ['\u{2175}', '\0', '\0']), ('\u{2166}', ['\u{2176}', '\0',
-        '\0']), ('\u{2167}', ['\u{2177}', '\0', '\0']), ('\u{2168}', ['\u{2178}', '\0', '\0']),
-        ('\u{2169}', ['\u{2179}', '\0', '\0']), ('\u{216a}', ['\u{217a}', '\0', '\0']), ('\u{216b}',
-        ['\u{217b}', '\0', '\0']), ('\u{216c}', ['\u{217c}', '\0', '\0']), ('\u{216d}', ['\u{217d}',
-        '\0', '\0']), ('\u{216e}', ['\u{217e}', '\0', '\0']), ('\u{216f}', ['\u{217f}', '\0',
-        '\0']), ('\u{2183}', ['\u{2184}', '\0', '\0']), ('\u{24b6}', ['\u{24d0}', '\0', '\0']),
-        ('\u{24b7}', ['\u{24d1}', '\0', '\0']), ('\u{24b8}', ['\u{24d2}', '\0', '\0']), ('\u{24b9}',
-        ['\u{24d3}', '\0', '\0']), ('\u{24ba}', ['\u{24d4}', '\0', '\0']), ('\u{24bb}', ['\u{24d5}',
-        '\0', '\0']), ('\u{24bc}', ['\u{24d6}', '\0', '\0']), ('\u{24bd}', ['\u{24d7}', '\0',
-        '\0']), ('\u{24be}', ['\u{24d8}', '\0', '\0']), ('\u{24bf}', ['\u{24d9}', '\0', '\0']),
-        ('\u{24c0}', ['\u{24da}', '\0', '\0']), ('\u{24c1}', ['\u{24db}', '\0', '\0']), ('\u{24c2}',
-        ['\u{24dc}', '\0', '\0']), ('\u{24c3}', ['\u{24dd}', '\0', '\0']), ('\u{24c4}', ['\u{24de}',
-        '\0', '\0']), ('\u{24c5}', ['\u{24df}', '\0', '\0']), ('\u{24c6}', ['\u{24e0}', '\0',
-        '\0']), ('\u{24c7}', ['\u{24e1}', '\0', '\0']), ('\u{24c8}', ['\u{24e2}', '\0', '\0']),
-        ('\u{24c9}', ['\u{24e3}', '\0', '\0']), ('\u{24ca}', ['\u{24e4}', '\0', '\0']), ('\u{24cb}',
-        ['\u{24e5}', '\0', '\0']), ('\u{24cc}', ['\u{24e6}', '\0', '\0']), ('\u{24cd}', ['\u{24e7}',
-        '\0', '\0']), ('\u{24ce}', ['\u{24e8}', '\0', '\0']), ('\u{24cf}', ['\u{24e9}', '\0',
-        '\0']), ('\u{2c00}', ['\u{2c30}', '\0', '\0']), ('\u{2c01}', ['\u{2c31}', '\0', '\0']),
-        ('\u{2c02}', ['\u{2c32}', '\0', '\0']), ('\u{2c03}', ['\u{2c33}', '\0', '\0']), ('\u{2c04}',
-        ['\u{2c34}', '\0', '\0']), ('\u{2c05}', ['\u{2c35}', '\0', '\0']), ('\u{2c06}', ['\u{2c36}',
-        '\0', '\0']), ('\u{2c07}', ['\u{2c37}', '\0', '\0']), ('\u{2c08}', ['\u{2c38}', '\0',
-        '\0']), ('\u{2c09}', ['\u{2c39}', '\0', '\0']), ('\u{2c0a}', ['\u{2c3a}', '\0', '\0']),
-        ('\u{2c0b}', ['\u{2c3b}', '\0', '\0']), ('\u{2c0c}', ['\u{2c3c}', '\0', '\0']), ('\u{2c0d}',
-        ['\u{2c3d}', '\0', '\0']), ('\u{2c0e}', ['\u{2c3e}', '\0', '\0']), ('\u{2c0f}', ['\u{2c3f}',
-        '\0', '\0']), ('\u{2c10}', ['\u{2c40}', '\0', '\0']), ('\u{2c11}', ['\u{2c41}', '\0',
-        '\0']), ('\u{2c12}', ['\u{2c42}', '\0', '\0']), ('\u{2c13}', ['\u{2c43}', '\0', '\0']),
-        ('\u{2c14}', ['\u{2c44}', '\0', '\0']), ('\u{2c15}', ['\u{2c45}', '\0', '\0']), ('\u{2c16}',
-        ['\u{2c46}', '\0', '\0']), ('\u{2c17}', ['\u{2c47}', '\0', '\0']), ('\u{2c18}', ['\u{2c48}',
-        '\0', '\0']), ('\u{2c19}', ['\u{2c49}', '\0', '\0']), ('\u{2c1a}', ['\u{2c4a}', '\0',
-        '\0']), ('\u{2c1b}', ['\u{2c4b}', '\0', '\0']), ('\u{2c1c}', ['\u{2c4c}', '\0', '\0']),
-        ('\u{2c1d}', ['\u{2c4d}', '\0', '\0']), ('\u{2c1e}', ['\u{2c4e}', '\0', '\0']), ('\u{2c1f}',
-        ['\u{2c4f}', '\0', '\0']), ('\u{2c20}', ['\u{2c50}', '\0', '\0']), ('\u{2c21}', ['\u{2c51}',
-        '\0', '\0']), ('\u{2c22}', ['\u{2c52}', '\0', '\0']), ('\u{2c23}', ['\u{2c53}', '\0',
-        '\0']), ('\u{2c24}', ['\u{2c54}', '\0', '\0']), ('\u{2c25}', ['\u{2c55}', '\0', '\0']),
-        ('\u{2c26}', ['\u{2c56}', '\0', '\0']), ('\u{2c27}', ['\u{2c57}', '\0', '\0']), ('\u{2c28}',
-        ['\u{2c58}', '\0', '\0']), ('\u{2c29}', ['\u{2c59}', '\0', '\0']), ('\u{2c2a}', ['\u{2c5a}',
-        '\0', '\0']), ('\u{2c2b}', ['\u{2c5b}', '\0', '\0']), ('\u{2c2c}', ['\u{2c5c}', '\0',
-        '\0']), ('\u{2c2d}', ['\u{2c5d}', '\0', '\0']), ('\u{2c2e}', ['\u{2c5e}', '\0', '\0']),
-        ('\u{2c60}', ['\u{2c61}', '\0', '\0']), ('\u{2c62}', ['\u{26b}', '\0', '\0']), ('\u{2c63}',
-        ['\u{1d7d}', '\0', '\0']), ('\u{2c64}', ['\u{27d}', '\0', '\0']), ('\u{2c67}', ['\u{2c68}',
-        '\0', '\0']), ('\u{2c69}', ['\u{2c6a}', '\0', '\0']), ('\u{2c6b}', ['\u{2c6c}', '\0',
-        '\0']), ('\u{2c6d}', ['\u{251}', '\0', '\0']), ('\u{2c6e}', ['\u{271}', '\0', '\0']),
-        ('\u{2c6f}', ['\u{250}', '\0', '\0']), ('\u{2c70}', ['\u{252}', '\0', '\0']), ('\u{2c72}',
-        ['\u{2c73}', '\0', '\0']), ('\u{2c75}', ['\u{2c76}', '\0', '\0']), ('\u{2c7e}', ['\u{23f}',
-        '\0', '\0']), ('\u{2c7f}', ['\u{240}', '\0', '\0']), ('\u{2c80}', ['\u{2c81}', '\0', '\0']),
-        ('\u{2c82}', ['\u{2c83}', '\0', '\0']), ('\u{2c84}', ['\u{2c85}', '\0', '\0']), ('\u{2c86}',
-        ['\u{2c87}', '\0', '\0']), ('\u{2c88}', ['\u{2c89}', '\0', '\0']), ('\u{2c8a}', ['\u{2c8b}',
-        '\0', '\0']), ('\u{2c8c}', ['\u{2c8d}', '\0', '\0']), ('\u{2c8e}', ['\u{2c8f}', '\0',
-        '\0']), ('\u{2c90}', ['\u{2c91}', '\0', '\0']), ('\u{2c92}', ['\u{2c93}', '\0', '\0']),
-        ('\u{2c94}', ['\u{2c95}', '\0', '\0']), ('\u{2c96}', ['\u{2c97}', '\0', '\0']), ('\u{2c98}',
-        ['\u{2c99}', '\0', '\0']), ('\u{2c9a}', ['\u{2c9b}', '\0', '\0']), ('\u{2c9c}', ['\u{2c9d}',
-        '\0', '\0']), ('\u{2c9e}', ['\u{2c9f}', '\0', '\0']), ('\u{2ca0}', ['\u{2ca1}', '\0',
-        '\0']), ('\u{2ca2}', ['\u{2ca3}', '\0', '\0']), ('\u{2ca4}', ['\u{2ca5}', '\0', '\0']),
-        ('\u{2ca6}', ['\u{2ca7}', '\0', '\0']), ('\u{2ca8}', ['\u{2ca9}', '\0', '\0']), ('\u{2caa}',
-        ['\u{2cab}', '\0', '\0']), ('\u{2cac}', ['\u{2cad}', '\0', '\0']), ('\u{2cae}', ['\u{2caf}',
-        '\0', '\0']), ('\u{2cb0}', ['\u{2cb1}', '\0', '\0']), ('\u{2cb2}', ['\u{2cb3}', '\0',
-        '\0']), ('\u{2cb4}', ['\u{2cb5}', '\0', '\0']), ('\u{2cb6}', ['\u{2cb7}', '\0', '\0']),
-        ('\u{2cb8}', ['\u{2cb9}', '\0', '\0']), ('\u{2cba}', ['\u{2cbb}', '\0', '\0']), ('\u{2cbc}',
-        ['\u{2cbd}', '\0', '\0']), ('\u{2cbe}', ['\u{2cbf}', '\0', '\0']), ('\u{2cc0}', ['\u{2cc1}',
-        '\0', '\0']), ('\u{2cc2}', ['\u{2cc3}', '\0', '\0']), ('\u{2cc4}', ['\u{2cc5}', '\0',
-        '\0']), ('\u{2cc6}', ['\u{2cc7}', '\0', '\0']), ('\u{2cc8}', ['\u{2cc9}', '\0', '\0']),
-        ('\u{2cca}', ['\u{2ccb}', '\0', '\0']), ('\u{2ccc}', ['\u{2ccd}', '\0', '\0']), ('\u{2cce}',
-        ['\u{2ccf}', '\0', '\0']), ('\u{2cd0}', ['\u{2cd1}', '\0', '\0']), ('\u{2cd2}', ['\u{2cd3}',
-        '\0', '\0']), ('\u{2cd4}', ['\u{2cd5}', '\0', '\0']), ('\u{2cd6}', ['\u{2cd7}', '\0',
-        '\0']), ('\u{2cd8}', ['\u{2cd9}', '\0', '\0']), ('\u{2cda}', ['\u{2cdb}', '\0', '\0']),
-        ('\u{2cdc}', ['\u{2cdd}', '\0', '\0']), ('\u{2cde}', ['\u{2cdf}', '\0', '\0']), ('\u{2ce0}',
-        ['\u{2ce1}', '\0', '\0']), ('\u{2ce2}', ['\u{2ce3}', '\0', '\0']), ('\u{2ceb}', ['\u{2cec}',
-        '\0', '\0']), ('\u{2ced}', ['\u{2cee}', '\0', '\0']), ('\u{2cf2}', ['\u{2cf3}', '\0',
-        '\0']), ('\u{a640}', ['\u{a641}', '\0', '\0']), ('\u{a642}', ['\u{a643}', '\0', '\0']),
-        ('\u{a644}', ['\u{a645}', '\0', '\0']), ('\u{a646}', ['\u{a647}', '\0', '\0']), ('\u{a648}',
-        ['\u{a649}', '\0', '\0']), ('\u{a64a}', ['\u{a64b}', '\0', '\0']), ('\u{a64c}', ['\u{a64d}',
-        '\0', '\0']), ('\u{a64e}', ['\u{a64f}', '\0', '\0']), ('\u{a650}', ['\u{a651}', '\0',
-        '\0']), ('\u{a652}', ['\u{a653}', '\0', '\0']), ('\u{a654}', ['\u{a655}', '\0', '\0']),
-        ('\u{a656}', ['\u{a657}', '\0', '\0']), ('\u{a658}', ['\u{a659}', '\0', '\0']), ('\u{a65a}',
-        ['\u{a65b}', '\0', '\0']), ('\u{a65c}', ['\u{a65d}', '\0', '\0']), ('\u{a65e}', ['\u{a65f}',
-        '\0', '\0']), ('\u{a660}', ['\u{a661}', '\0', '\0']), ('\u{a662}', ['\u{a663}', '\0',
-        '\0']), ('\u{a664}', ['\u{a665}', '\0', '\0']), ('\u{a666}', ['\u{a667}', '\0', '\0']),
-        ('\u{a668}', ['\u{a669}', '\0', '\0']), ('\u{a66a}', ['\u{a66b}', '\0', '\0']), ('\u{a66c}',
-        ['\u{a66d}', '\0', '\0']), ('\u{a680}', ['\u{a681}', '\0', '\0']), ('\u{a682}', ['\u{a683}',
-        '\0', '\0']), ('\u{a684}', ['\u{a685}', '\0', '\0']), ('\u{a686}', ['\u{a687}', '\0',
-        '\0']), ('\u{a688}', ['\u{a689}', '\0', '\0']), ('\u{a68a}', ['\u{a68b}', '\0', '\0']),
-        ('\u{a68c}', ['\u{a68d}', '\0', '\0']), ('\u{a68e}', ['\u{a68f}', '\0', '\0']), ('\u{a690}',
-        ['\u{a691}', '\0', '\0']), ('\u{a692}', ['\u{a693}', '\0', '\0']), ('\u{a694}', ['\u{a695}',
-        '\0', '\0']), ('\u{a696}', ['\u{a697}', '\0', '\0']), ('\u{a698}', ['\u{a699}', '\0',
-        '\0']), ('\u{a69a}', ['\u{a69b}', '\0', '\0']), ('\u{a722}', ['\u{a723}', '\0', '\0']),
-        ('\u{a724}', ['\u{a725}', '\0', '\0']), ('\u{a726}', ['\u{a727}', '\0', '\0']), ('\u{a728}',
-        ['\u{a729}', '\0', '\0']), ('\u{a72a}', ['\u{a72b}', '\0', '\0']), ('\u{a72c}', ['\u{a72d}',
-        '\0', '\0']), ('\u{a72e}', ['\u{a72f}', '\0', '\0']), ('\u{a732}', ['\u{a733}', '\0',
-        '\0']), ('\u{a734}', ['\u{a735}', '\0', '\0']), ('\u{a736}', ['\u{a737}', '\0', '\0']),
-        ('\u{a738}', ['\u{a739}', '\0', '\0']), ('\u{a73a}', ['\u{a73b}', '\0', '\0']), ('\u{a73c}',
-        ['\u{a73d}', '\0', '\0']), ('\u{a73e}', ['\u{a73f}', '\0', '\0']), ('\u{a740}', ['\u{a741}',
-        '\0', '\0']), ('\u{a742}', ['\u{a743}', '\0', '\0']), ('\u{a744}', ['\u{a745}', '\0',
-        '\0']), ('\u{a746}', ['\u{a747}', '\0', '\0']), ('\u{a748}', ['\u{a749}', '\0', '\0']),
-        ('\u{a74a}', ['\u{a74b}', '\0', '\0']), ('\u{a74c}', ['\u{a74d}', '\0', '\0']), ('\u{a74e}',
-        ['\u{a74f}', '\0', '\0']), ('\u{a750}', ['\u{a751}', '\0', '\0']), ('\u{a752}', ['\u{a753}',
-        '\0', '\0']), ('\u{a754}', ['\u{a755}', '\0', '\0']), ('\u{a756}', ['\u{a757}', '\0',
-        '\0']), ('\u{a758}', ['\u{a759}', '\0', '\0']), ('\u{a75a}', ['\u{a75b}', '\0', '\0']),
-        ('\u{a75c}', ['\u{a75d}', '\0', '\0']), ('\u{a75e}', ['\u{a75f}', '\0', '\0']), ('\u{a760}',
-        ['\u{a761}', '\0', '\0']), ('\u{a762}', ['\u{a763}', '\0', '\0']), ('\u{a764}', ['\u{a765}',
-        '\0', '\0']), ('\u{a766}', ['\u{a767}', '\0', '\0']), ('\u{a768}', ['\u{a769}', '\0',
-        '\0']), ('\u{a76a}', ['\u{a76b}', '\0', '\0']), ('\u{a76c}', ['\u{a76d}', '\0', '\0']),
-        ('\u{a76e}', ['\u{a76f}', '\0', '\0']), ('\u{a779}', ['\u{a77a}', '\0', '\0']), ('\u{a77b}',
-        ['\u{a77c}', '\0', '\0']), ('\u{a77d}', ['\u{1d79}', '\0', '\0']), ('\u{a77e}', ['\u{a77f}',
-        '\0', '\0']), ('\u{a780}', ['\u{a781}', '\0', '\0']), ('\u{a782}', ['\u{a783}', '\0',
-        '\0']), ('\u{a784}', ['\u{a785}', '\0', '\0']), ('\u{a786}', ['\u{a787}', '\0', '\0']),
-        ('\u{a78b}', ['\u{a78c}', '\0', '\0']), ('\u{a78d}', ['\u{265}', '\0', '\0']), ('\u{a790}',
-        ['\u{a791}', '\0', '\0']), ('\u{a792}', ['\u{a793}', '\0', '\0']), ('\u{a796}', ['\u{a797}',
-        '\0', '\0']), ('\u{a798}', ['\u{a799}', '\0', '\0']), ('\u{a79a}', ['\u{a79b}', '\0',
-        '\0']), ('\u{a79c}', ['\u{a79d}', '\0', '\0']), ('\u{a79e}', ['\u{a79f}', '\0', '\0']),
-        ('\u{a7a0}', ['\u{a7a1}', '\0', '\0']), ('\u{a7a2}', ['\u{a7a3}', '\0', '\0']), ('\u{a7a4}',
-        ['\u{a7a5}', '\0', '\0']), ('\u{a7a6}', ['\u{a7a7}', '\0', '\0']), ('\u{a7a8}', ['\u{a7a9}',
-        '\0', '\0']), ('\u{a7aa}', ['\u{266}', '\0', '\0']), ('\u{a7ab}', ['\u{25c}', '\0', '\0']),
-        ('\u{a7ac}', ['\u{261}', '\0', '\0']), ('\u{a7ad}', ['\u{26c}', '\0', '\0']), ('\u{a7ae}',
-        ['\u{26a}', '\0', '\0']), ('\u{a7b0}', ['\u{29e}', '\0', '\0']), ('\u{a7b1}', ['\u{287}',
-        '\0', '\0']), ('\u{a7b2}', ['\u{29d}', '\0', '\0']), ('\u{a7b3}', ['\u{ab53}', '\0', '\0']),
-        ('\u{a7b4}', ['\u{a7b5}', '\0', '\0']), ('\u{a7b6}', ['\u{a7b7}', '\0', '\0']), ('\u{ff21}',
-        ['\u{ff41}', '\0', '\0']), ('\u{ff22}', ['\u{ff42}', '\0', '\0']), ('\u{ff23}', ['\u{ff43}',
-        '\0', '\0']), ('\u{ff24}', ['\u{ff44}', '\0', '\0']), ('\u{ff25}', ['\u{ff45}', '\0',
-        '\0']), ('\u{ff26}', ['\u{ff46}', '\0', '\0']), ('\u{ff27}', ['\u{ff47}', '\0', '\0']),
-        ('\u{ff28}', ['\u{ff48}', '\0', '\0']), ('\u{ff29}', ['\u{ff49}', '\0', '\0']), ('\u{ff2a}',
-        ['\u{ff4a}', '\0', '\0']), ('\u{ff2b}', ['\u{ff4b}', '\0', '\0']), ('\u{ff2c}', ['\u{ff4c}',
-        '\0', '\0']), ('\u{ff2d}', ['\u{ff4d}', '\0', '\0']), ('\u{ff2e}', ['\u{ff4e}', '\0',
-        '\0']), ('\u{ff2f}', ['\u{ff4f}', '\0', '\0']), ('\u{ff30}', ['\u{ff50}', '\0', '\0']),
-        ('\u{ff31}', ['\u{ff51}', '\0', '\0']), ('\u{ff32}', ['\u{ff52}', '\0', '\0']), ('\u{ff33}',
-        ['\u{ff53}', '\0', '\0']), ('\u{ff34}', ['\u{ff54}', '\0', '\0']), ('\u{ff35}', ['\u{ff55}',
-        '\0', '\0']), ('\u{ff36}', ['\u{ff56}', '\0', '\0']), ('\u{ff37}', ['\u{ff57}', '\0',
-        '\0']), ('\u{ff38}', ['\u{ff58}', '\0', '\0']), ('\u{ff39}', ['\u{ff59}', '\0', '\0']),
-        ('\u{ff3a}', ['\u{ff5a}', '\0', '\0']), ('\u{10400}', ['\u{10428}', '\0', '\0']),
-        ('\u{10401}', ['\u{10429}', '\0', '\0']), ('\u{10402}', ['\u{1042a}', '\0', '\0']),
-        ('\u{10403}', ['\u{1042b}', '\0', '\0']), ('\u{10404}', ['\u{1042c}', '\0', '\0']),
-        ('\u{10405}', ['\u{1042d}', '\0', '\0']), ('\u{10406}', ['\u{1042e}', '\0', '\0']),
-        ('\u{10407}', ['\u{1042f}', '\0', '\0']), ('\u{10408}', ['\u{10430}', '\0', '\0']),
-        ('\u{10409}', ['\u{10431}', '\0', '\0']), ('\u{1040a}', ['\u{10432}', '\0', '\0']),
-        ('\u{1040b}', ['\u{10433}', '\0', '\0']), ('\u{1040c}', ['\u{10434}', '\0', '\0']),
-        ('\u{1040d}', ['\u{10435}', '\0', '\0']), ('\u{1040e}', ['\u{10436}', '\0', '\0']),
-        ('\u{1040f}', ['\u{10437}', '\0', '\0']), ('\u{10410}', ['\u{10438}', '\0', '\0']),
-        ('\u{10411}', ['\u{10439}', '\0', '\0']), ('\u{10412}', ['\u{1043a}', '\0', '\0']),
-        ('\u{10413}', ['\u{1043b}', '\0', '\0']), ('\u{10414}', ['\u{1043c}', '\0', '\0']),
-        ('\u{10415}', ['\u{1043d}', '\0', '\0']), ('\u{10416}', ['\u{1043e}', '\0', '\0']),
-        ('\u{10417}', ['\u{1043f}', '\0', '\0']), ('\u{10418}', ['\u{10440}', '\0', '\0']),
-        ('\u{10419}', ['\u{10441}', '\0', '\0']), ('\u{1041a}', ['\u{10442}', '\0', '\0']),
-        ('\u{1041b}', ['\u{10443}', '\0', '\0']), ('\u{1041c}', ['\u{10444}', '\0', '\0']),
-        ('\u{1041d}', ['\u{10445}', '\0', '\0']), ('\u{1041e}', ['\u{10446}', '\0', '\0']),
-        ('\u{1041f}', ['\u{10447}', '\0', '\0']), ('\u{10420}', ['\u{10448}', '\0', '\0']),
-        ('\u{10421}', ['\u{10449}', '\0', '\0']), ('\u{10422}', ['\u{1044a}', '\0', '\0']),
-        ('\u{10423}', ['\u{1044b}', '\0', '\0']), ('\u{10424}', ['\u{1044c}', '\0', '\0']),
-        ('\u{10425}', ['\u{1044d}', '\0', '\0']), ('\u{10426}', ['\u{1044e}', '\0', '\0']),
-        ('\u{10427}', ['\u{1044f}', '\0', '\0']), ('\u{104b0}', ['\u{104d8}', '\0', '\0']),
-        ('\u{104b1}', ['\u{104d9}', '\0', '\0']), ('\u{104b2}', ['\u{104da}', '\0', '\0']),
-        ('\u{104b3}', ['\u{104db}', '\0', '\0']), ('\u{104b4}', ['\u{104dc}', '\0', '\0']),
-        ('\u{104b5}', ['\u{104dd}', '\0', '\0']), ('\u{104b6}', ['\u{104de}', '\0', '\0']),
-        ('\u{104b7}', ['\u{104df}', '\0', '\0']), ('\u{104b8}', ['\u{104e0}', '\0', '\0']),
-        ('\u{104b9}', ['\u{104e1}', '\0', '\0']), ('\u{104ba}', ['\u{104e2}', '\0', '\0']),
-        ('\u{104bb}', ['\u{104e3}', '\0', '\0']), ('\u{104bc}', ['\u{104e4}', '\0', '\0']),
-        ('\u{104bd}', ['\u{104e5}', '\0', '\0']), ('\u{104be}', ['\u{104e6}', '\0', '\0']),
-        ('\u{104bf}', ['\u{104e7}', '\0', '\0']), ('\u{104c0}', ['\u{104e8}', '\0', '\0']),
-        ('\u{104c1}', ['\u{104e9}', '\0', '\0']), ('\u{104c2}', ['\u{104ea}', '\0', '\0']),
-        ('\u{104c3}', ['\u{104eb}', '\0', '\0']), ('\u{104c4}', ['\u{104ec}', '\0', '\0']),
-        ('\u{104c5}', ['\u{104ed}', '\0', '\0']), ('\u{104c6}', ['\u{104ee}', '\0', '\0']),
-        ('\u{104c7}', ['\u{104ef}', '\0', '\0']), ('\u{104c8}', ['\u{104f0}', '\0', '\0']),
-        ('\u{104c9}', ['\u{104f1}', '\0', '\0']), ('\u{104ca}', ['\u{104f2}', '\0', '\0']),
-        ('\u{104cb}', ['\u{104f3}', '\0', '\0']), ('\u{104cc}', ['\u{104f4}', '\0', '\0']),
-        ('\u{104cd}', ['\u{104f5}', '\0', '\0']), ('\u{104ce}', ['\u{104f6}', '\0', '\0']),
-        ('\u{104cf}', ['\u{104f7}', '\0', '\0']), ('\u{104d0}', ['\u{104f8}', '\0', '\0']),
-        ('\u{104d1}', ['\u{104f9}', '\0', '\0']), ('\u{104d2}', ['\u{104fa}', '\0', '\0']),
-        ('\u{104d3}', ['\u{104fb}', '\0', '\0']), ('\u{10c80}', ['\u{10cc0}', '\0', '\0']),
-        ('\u{10c81}', ['\u{10cc1}', '\0', '\0']), ('\u{10c82}', ['\u{10cc2}', '\0', '\0']),
-        ('\u{10c83}', ['\u{10cc3}', '\0', '\0']), ('\u{10c84}', ['\u{10cc4}', '\0', '\0']),
-        ('\u{10c85}', ['\u{10cc5}', '\0', '\0']), ('\u{10c86}', ['\u{10cc6}', '\0', '\0']),
-        ('\u{10c87}', ['\u{10cc7}', '\0', '\0']), ('\u{10c88}', ['\u{10cc8}', '\0', '\0']),
-        ('\u{10c89}', ['\u{10cc9}', '\0', '\0']), ('\u{10c8a}', ['\u{10cca}', '\0', '\0']),
-        ('\u{10c8b}', ['\u{10ccb}', '\0', '\0']), ('\u{10c8c}', ['\u{10ccc}', '\0', '\0']),
-        ('\u{10c8d}', ['\u{10ccd}', '\0', '\0']), ('\u{10c8e}', ['\u{10cce}', '\0', '\0']),
-        ('\u{10c8f}', ['\u{10ccf}', '\0', '\0']), ('\u{10c90}', ['\u{10cd0}', '\0', '\0']),
-        ('\u{10c91}', ['\u{10cd1}', '\0', '\0']), ('\u{10c92}', ['\u{10cd2}', '\0', '\0']),
-        ('\u{10c93}', ['\u{10cd3}', '\0', '\0']), ('\u{10c94}', ['\u{10cd4}', '\0', '\0']),
-        ('\u{10c95}', ['\u{10cd5}', '\0', '\0']), ('\u{10c96}', ['\u{10cd6}', '\0', '\0']),
-        ('\u{10c97}', ['\u{10cd7}', '\0', '\0']), ('\u{10c98}', ['\u{10cd8}', '\0', '\0']),
-        ('\u{10c99}', ['\u{10cd9}', '\0', '\0']), ('\u{10c9a}', ['\u{10cda}', '\0', '\0']),
-        ('\u{10c9b}', ['\u{10cdb}', '\0', '\0']), ('\u{10c9c}', ['\u{10cdc}', '\0', '\0']),
-        ('\u{10c9d}', ['\u{10cdd}', '\0', '\0']), ('\u{10c9e}', ['\u{10cde}', '\0', '\0']),
-        ('\u{10c9f}', ['\u{10cdf}', '\0', '\0']), ('\u{10ca0}', ['\u{10ce0}', '\0', '\0']),
-        ('\u{10ca1}', ['\u{10ce1}', '\0', '\0']), ('\u{10ca2}', ['\u{10ce2}', '\0', '\0']),
-        ('\u{10ca3}', ['\u{10ce3}', '\0', '\0']), ('\u{10ca4}', ['\u{10ce4}', '\0', '\0']),
-        ('\u{10ca5}', ['\u{10ce5}', '\0', '\0']), ('\u{10ca6}', ['\u{10ce6}', '\0', '\0']),
-        ('\u{10ca7}', ['\u{10ce7}', '\0', '\0']), ('\u{10ca8}', ['\u{10ce8}', '\0', '\0']),
-        ('\u{10ca9}', ['\u{10ce9}', '\0', '\0']), ('\u{10caa}', ['\u{10cea}', '\0', '\0']),
-        ('\u{10cab}', ['\u{10ceb}', '\0', '\0']), ('\u{10cac}', ['\u{10cec}', '\0', '\0']),
-        ('\u{10cad}', ['\u{10ced}', '\0', '\0']), ('\u{10cae}', ['\u{10cee}', '\0', '\0']),
-        ('\u{10caf}', ['\u{10cef}', '\0', '\0']), ('\u{10cb0}', ['\u{10cf0}', '\0', '\0']),
-        ('\u{10cb1}', ['\u{10cf1}', '\0', '\0']), ('\u{10cb2}', ['\u{10cf2}', '\0', '\0']),
-        ('\u{118a0}', ['\u{118c0}', '\0', '\0']), ('\u{118a1}', ['\u{118c1}', '\0', '\0']),
-        ('\u{118a2}', ['\u{118c2}', '\0', '\0']), ('\u{118a3}', ['\u{118c3}', '\0', '\0']),
-        ('\u{118a4}', ['\u{118c4}', '\0', '\0']), ('\u{118a5}', ['\u{118c5}', '\0', '\0']),
-        ('\u{118a6}', ['\u{118c6}', '\0', '\0']), ('\u{118a7}', ['\u{118c7}', '\0', '\0']),
-        ('\u{118a8}', ['\u{118c8}', '\0', '\0']), ('\u{118a9}', ['\u{118c9}', '\0', '\0']),
-        ('\u{118aa}', ['\u{118ca}', '\0', '\0']), ('\u{118ab}', ['\u{118cb}', '\0', '\0']),
-        ('\u{118ac}', ['\u{118cc}', '\0', '\0']), ('\u{118ad}', ['\u{118cd}', '\0', '\0']),
-        ('\u{118ae}', ['\u{118ce}', '\0', '\0']), ('\u{118af}', ['\u{118cf}', '\0', '\0']),
-        ('\u{118b0}', ['\u{118d0}', '\0', '\0']), ('\u{118b1}', ['\u{118d1}', '\0', '\0']),
-        ('\u{118b2}', ['\u{118d2}', '\0', '\0']), ('\u{118b3}', ['\u{118d3}', '\0', '\0']),
-        ('\u{118b4}', ['\u{118d4}', '\0', '\0']), ('\u{118b5}', ['\u{118d5}', '\0', '\0']),
-        ('\u{118b6}', ['\u{118d6}', '\0', '\0']), ('\u{118b7}', ['\u{118d7}', '\0', '\0']),
-        ('\u{118b8}', ['\u{118d8}', '\0', '\0']), ('\u{118b9}', ['\u{118d9}', '\0', '\0']),
-        ('\u{118ba}', ['\u{118da}', '\0', '\0']), ('\u{118bb}', ['\u{118db}', '\0', '\0']),
-        ('\u{118bc}', ['\u{118dc}', '\0', '\0']), ('\u{118bd}', ['\u{118dd}', '\0', '\0']),
-        ('\u{118be}', ['\u{118de}', '\0', '\0']), ('\u{118bf}', ['\u{118df}', '\0', '\0']),
-        ('\u{1e900}', ['\u{1e922}', '\0', '\0']), ('\u{1e901}', ['\u{1e923}', '\0', '\0']),
-        ('\u{1e902}', ['\u{1e924}', '\0', '\0']), ('\u{1e903}', ['\u{1e925}', '\0', '\0']),
-        ('\u{1e904}', ['\u{1e926}', '\0', '\0']), ('\u{1e905}', ['\u{1e927}', '\0', '\0']),
-        ('\u{1e906}', ['\u{1e928}', '\0', '\0']), ('\u{1e907}', ['\u{1e929}', '\0', '\0']),
-        ('\u{1e908}', ['\u{1e92a}', '\0', '\0']), ('\u{1e909}', ['\u{1e92b}', '\0', '\0']),
-        ('\u{1e90a}', ['\u{1e92c}', '\0', '\0']), ('\u{1e90b}', ['\u{1e92d}', '\0', '\0']),
-        ('\u{1e90c}', ['\u{1e92e}', '\0', '\0']), ('\u{1e90d}', ['\u{1e92f}', '\0', '\0']),
-        ('\u{1e90e}', ['\u{1e930}', '\0', '\0']), ('\u{1e90f}', ['\u{1e931}', '\0', '\0']),
-        ('\u{1e910}', ['\u{1e932}', '\0', '\0']), ('\u{1e911}', ['\u{1e933}', '\0', '\0']),
-        ('\u{1e912}', ['\u{1e934}', '\0', '\0']), ('\u{1e913}', ['\u{1e935}', '\0', '\0']),
-        ('\u{1e914}', ['\u{1e936}', '\0', '\0']), ('\u{1e915}', ['\u{1e937}', '\0', '\0']),
-        ('\u{1e916}', ['\u{1e938}', '\0', '\0']), ('\u{1e917}', ['\u{1e939}', '\0', '\0']),
-        ('\u{1e918}', ['\u{1e93a}', '\0', '\0']), ('\u{1e919}', ['\u{1e93b}', '\0', '\0']),
-        ('\u{1e91a}', ['\u{1e93c}', '\0', '\0']), ('\u{1e91b}', ['\u{1e93d}', '\0', '\0']),
-        ('\u{1e91c}', ['\u{1e93e}', '\0', '\0']), ('\u{1e91d}', ['\u{1e93f}', '\0', '\0']),
-        ('\u{1e91e}', ['\u{1e940}', '\0', '\0']), ('\u{1e91f}', ['\u{1e941}', '\0', '\0']),
-        ('\u{1e920}', ['\u{1e942}', '\0', '\0']), ('\u{1e921}', ['\u{1e943}', '\0', '\0'])
+        '\0']), ('\u{13f5}', ['\u{13fd}', '\0', '\0']), ('\u{1c90}', ['\u{10d0}', '\0', '\0']),
+        ('\u{1c91}', ['\u{10d1}', '\0', '\0']), ('\u{1c92}', ['\u{10d2}', '\0', '\0']), ('\u{1c93}',
+        ['\u{10d3}', '\0', '\0']), ('\u{1c94}', ['\u{10d4}', '\0', '\0']), ('\u{1c95}', ['\u{10d5}',
+        '\0', '\0']), ('\u{1c96}', ['\u{10d6}', '\0', '\0']), ('\u{1c97}', ['\u{10d7}', '\0',
+        '\0']), ('\u{1c98}', ['\u{10d8}', '\0', '\0']), ('\u{1c99}', ['\u{10d9}', '\0', '\0']),
+        ('\u{1c9a}', ['\u{10da}', '\0', '\0']), ('\u{1c9b}', ['\u{10db}', '\0', '\0']), ('\u{1c9c}',
+        ['\u{10dc}', '\0', '\0']), ('\u{1c9d}', ['\u{10dd}', '\0', '\0']), ('\u{1c9e}', ['\u{10de}',
+        '\0', '\0']), ('\u{1c9f}', ['\u{10df}', '\0', '\0']), ('\u{1ca0}', ['\u{10e0}', '\0',
+        '\0']), ('\u{1ca1}', ['\u{10e1}', '\0', '\0']), ('\u{1ca2}', ['\u{10e2}', '\0', '\0']),
+        ('\u{1ca3}', ['\u{10e3}', '\0', '\0']), ('\u{1ca4}', ['\u{10e4}', '\0', '\0']), ('\u{1ca5}',
+        ['\u{10e5}', '\0', '\0']), ('\u{1ca6}', ['\u{10e6}', '\0', '\0']), ('\u{1ca7}', ['\u{10e7}',
+        '\0', '\0']), ('\u{1ca8}', ['\u{10e8}', '\0', '\0']), ('\u{1ca9}', ['\u{10e9}', '\0',
+        '\0']), ('\u{1caa}', ['\u{10ea}', '\0', '\0']), ('\u{1cab}', ['\u{10eb}', '\0', '\0']),
+        ('\u{1cac}', ['\u{10ec}', '\0', '\0']), ('\u{1cad}', ['\u{10ed}', '\0', '\0']), ('\u{1cae}',
+        ['\u{10ee}', '\0', '\0']), ('\u{1caf}', ['\u{10ef}', '\0', '\0']), ('\u{1cb0}', ['\u{10f0}',
+        '\0', '\0']), ('\u{1cb1}', ['\u{10f1}', '\0', '\0']), ('\u{1cb2}', ['\u{10f2}', '\0',
+        '\0']), ('\u{1cb3}', ['\u{10f3}', '\0', '\0']), ('\u{1cb4}', ['\u{10f4}', '\0', '\0']),
+        ('\u{1cb5}', ['\u{10f5}', '\0', '\0']), ('\u{1cb6}', ['\u{10f6}', '\0', '\0']), ('\u{1cb7}',
+        ['\u{10f7}', '\0', '\0']), ('\u{1cb8}', ['\u{10f8}', '\0', '\0']), ('\u{1cb9}', ['\u{10f9}',
+        '\0', '\0']), ('\u{1cba}', ['\u{10fa}', '\0', '\0']), ('\u{1cbd}', ['\u{10fd}', '\0',
+        '\0']), ('\u{1cbe}', ['\u{10fe}', '\0', '\0']), ('\u{1cbf}', ['\u{10ff}', '\0', '\0']),
+        ('\u{1e00}', ['\u{1e01}', '\0', '\0']), ('\u{1e02}', ['\u{1e03}', '\0', '\0']), ('\u{1e04}',
+        ['\u{1e05}', '\0', '\0']), ('\u{1e06}', ['\u{1e07}', '\0', '\0']), ('\u{1e08}', ['\u{1e09}',
+        '\0', '\0']), ('\u{1e0a}', ['\u{1e0b}', '\0', '\0']), ('\u{1e0c}', ['\u{1e0d}', '\0',
+        '\0']), ('\u{1e0e}', ['\u{1e0f}', '\0', '\0']), ('\u{1e10}', ['\u{1e11}', '\0', '\0']),
+        ('\u{1e12}', ['\u{1e13}', '\0', '\0']), ('\u{1e14}', ['\u{1e15}', '\0', '\0']), ('\u{1e16}',
+        ['\u{1e17}', '\0', '\0']), ('\u{1e18}', ['\u{1e19}', '\0', '\0']), ('\u{1e1a}', ['\u{1e1b}',
+        '\0', '\0']), ('\u{1e1c}', ['\u{1e1d}', '\0', '\0']), ('\u{1e1e}', ['\u{1e1f}', '\0',
+        '\0']), ('\u{1e20}', ['\u{1e21}', '\0', '\0']), ('\u{1e22}', ['\u{1e23}', '\0', '\0']),
+        ('\u{1e24}', ['\u{1e25}', '\0', '\0']), ('\u{1e26}', ['\u{1e27}', '\0', '\0']), ('\u{1e28}',
+        ['\u{1e29}', '\0', '\0']), ('\u{1e2a}', ['\u{1e2b}', '\0', '\0']), ('\u{1e2c}', ['\u{1e2d}',
+        '\0', '\0']), ('\u{1e2e}', ['\u{1e2f}', '\0', '\0']), ('\u{1e30}', ['\u{1e31}', '\0',
+        '\0']), ('\u{1e32}', ['\u{1e33}', '\0', '\0']), ('\u{1e34}', ['\u{1e35}', '\0', '\0']),
+        ('\u{1e36}', ['\u{1e37}', '\0', '\0']), ('\u{1e38}', ['\u{1e39}', '\0', '\0']), ('\u{1e3a}',
+        ['\u{1e3b}', '\0', '\0']), ('\u{1e3c}', ['\u{1e3d}', '\0', '\0']), ('\u{1e3e}', ['\u{1e3f}',
+        '\0', '\0']), ('\u{1e40}', ['\u{1e41}', '\0', '\0']), ('\u{1e42}', ['\u{1e43}', '\0',
+        '\0']), ('\u{1e44}', ['\u{1e45}', '\0', '\0']), ('\u{1e46}', ['\u{1e47}', '\0', '\0']),
+        ('\u{1e48}', ['\u{1e49}', '\0', '\0']), ('\u{1e4a}', ['\u{1e4b}', '\0', '\0']), ('\u{1e4c}',
+        ['\u{1e4d}', '\0', '\0']), ('\u{1e4e}', ['\u{1e4f}', '\0', '\0']), ('\u{1e50}', ['\u{1e51}',
+        '\0', '\0']), ('\u{1e52}', ['\u{1e53}', '\0', '\0']), ('\u{1e54}', ['\u{1e55}', '\0',
+        '\0']), ('\u{1e56}', ['\u{1e57}', '\0', '\0']), ('\u{1e58}', ['\u{1e59}', '\0', '\0']),
+        ('\u{1e5a}', ['\u{1e5b}', '\0', '\0']), ('\u{1e5c}', ['\u{1e5d}', '\0', '\0']), ('\u{1e5e}',
+        ['\u{1e5f}', '\0', '\0']), ('\u{1e60}', ['\u{1e61}', '\0', '\0']), ('\u{1e62}', ['\u{1e63}',
+        '\0', '\0']), ('\u{1e64}', ['\u{1e65}', '\0', '\0']), ('\u{1e66}', ['\u{1e67}', '\0',
+        '\0']), ('\u{1e68}', ['\u{1e69}', '\0', '\0']), ('\u{1e6a}', ['\u{1e6b}', '\0', '\0']),
+        ('\u{1e6c}', ['\u{1e6d}', '\0', '\0']), ('\u{1e6e}', ['\u{1e6f}', '\0', '\0']), ('\u{1e70}',
+        ['\u{1e71}', '\0', '\0']), ('\u{1e72}', ['\u{1e73}', '\0', '\0']), ('\u{1e74}', ['\u{1e75}',
+        '\0', '\0']), ('\u{1e76}', ['\u{1e77}', '\0', '\0']), ('\u{1e78}', ['\u{1e79}', '\0',
+        '\0']), ('\u{1e7a}', ['\u{1e7b}', '\0', '\0']), ('\u{1e7c}', ['\u{1e7d}', '\0', '\0']),
+        ('\u{1e7e}', ['\u{1e7f}', '\0', '\0']), ('\u{1e80}', ['\u{1e81}', '\0', '\0']), ('\u{1e82}',
+        ['\u{1e83}', '\0', '\0']), ('\u{1e84}', ['\u{1e85}', '\0', '\0']), ('\u{1e86}', ['\u{1e87}',
+        '\0', '\0']), ('\u{1e88}', ['\u{1e89}', '\0', '\0']), ('\u{1e8a}', ['\u{1e8b}', '\0',
+        '\0']), ('\u{1e8c}', ['\u{1e8d}', '\0', '\0']), ('\u{1e8e}', ['\u{1e8f}', '\0', '\0']),
+        ('\u{1e90}', ['\u{1e91}', '\0', '\0']), ('\u{1e92}', ['\u{1e93}', '\0', '\0']), ('\u{1e94}',
+        ['\u{1e95}', '\0', '\0']), ('\u{1e9e}', ['\u{df}', '\0', '\0']), ('\u{1ea0}', ['\u{1ea1}',
+        '\0', '\0']), ('\u{1ea2}', ['\u{1ea3}', '\0', '\0']), ('\u{1ea4}', ['\u{1ea5}', '\0',
+        '\0']), ('\u{1ea6}', ['\u{1ea7}', '\0', '\0']), ('\u{1ea8}', ['\u{1ea9}', '\0', '\0']),
+        ('\u{1eaa}', ['\u{1eab}', '\0', '\0']), ('\u{1eac}', ['\u{1ead}', '\0', '\0']), ('\u{1eae}',
+        ['\u{1eaf}', '\0', '\0']), ('\u{1eb0}', ['\u{1eb1}', '\0', '\0']), ('\u{1eb2}', ['\u{1eb3}',
+        '\0', '\0']), ('\u{1eb4}', ['\u{1eb5}', '\0', '\0']), ('\u{1eb6}', ['\u{1eb7}', '\0',
+        '\0']), ('\u{1eb8}', ['\u{1eb9}', '\0', '\0']), ('\u{1eba}', ['\u{1ebb}', '\0', '\0']),
+        ('\u{1ebc}', ['\u{1ebd}', '\0', '\0']), ('\u{1ebe}', ['\u{1ebf}', '\0', '\0']), ('\u{1ec0}',
+        ['\u{1ec1}', '\0', '\0']), ('\u{1ec2}', ['\u{1ec3}', '\0', '\0']), ('\u{1ec4}', ['\u{1ec5}',
+        '\0', '\0']), ('\u{1ec6}', ['\u{1ec7}', '\0', '\0']), ('\u{1ec8}', ['\u{1ec9}', '\0',
+        '\0']), ('\u{1eca}', ['\u{1ecb}', '\0', '\0']), ('\u{1ecc}', ['\u{1ecd}', '\0', '\0']),
+        ('\u{1ece}', ['\u{1ecf}', '\0', '\0']), ('\u{1ed0}', ['\u{1ed1}', '\0', '\0']), ('\u{1ed2}',
+        ['\u{1ed3}', '\0', '\0']), ('\u{1ed4}', ['\u{1ed5}', '\0', '\0']), ('\u{1ed6}', ['\u{1ed7}',
+        '\0', '\0']), ('\u{1ed8}', ['\u{1ed9}', '\0', '\0']), ('\u{1eda}', ['\u{1edb}', '\0',
+        '\0']), ('\u{1edc}', ['\u{1edd}', '\0', '\0']), ('\u{1ede}', ['\u{1edf}', '\0', '\0']),
+        ('\u{1ee0}', ['\u{1ee1}', '\0', '\0']), ('\u{1ee2}', ['\u{1ee3}', '\0', '\0']), ('\u{1ee4}',
+        ['\u{1ee5}', '\0', '\0']), ('\u{1ee6}', ['\u{1ee7}', '\0', '\0']), ('\u{1ee8}', ['\u{1ee9}',
+        '\0', '\0']), ('\u{1eea}', ['\u{1eeb}', '\0', '\0']), ('\u{1eec}', ['\u{1eed}', '\0',
+        '\0']), ('\u{1eee}', ['\u{1eef}', '\0', '\0']), ('\u{1ef0}', ['\u{1ef1}', '\0', '\0']),
+        ('\u{1ef2}', ['\u{1ef3}', '\0', '\0']), ('\u{1ef4}', ['\u{1ef5}', '\0', '\0']), ('\u{1ef6}',
+        ['\u{1ef7}', '\0', '\0']), ('\u{1ef8}', ['\u{1ef9}', '\0', '\0']), ('\u{1efa}', ['\u{1efb}',
+        '\0', '\0']), ('\u{1efc}', ['\u{1efd}', '\0', '\0']), ('\u{1efe}', ['\u{1eff}', '\0',
+        '\0']), ('\u{1f08}', ['\u{1f00}', '\0', '\0']), ('\u{1f09}', ['\u{1f01}', '\0', '\0']),
+        ('\u{1f0a}', ['\u{1f02}', '\0', '\0']), ('\u{1f0b}', ['\u{1f03}', '\0', '\0']), ('\u{1f0c}',
+        ['\u{1f04}', '\0', '\0']), ('\u{1f0d}', ['\u{1f05}', '\0', '\0']), ('\u{1f0e}', ['\u{1f06}',
+        '\0', '\0']), ('\u{1f0f}', ['\u{1f07}', '\0', '\0']), ('\u{1f18}', ['\u{1f10}', '\0',
+        '\0']), ('\u{1f19}', ['\u{1f11}', '\0', '\0']), ('\u{1f1a}', ['\u{1f12}', '\0', '\0']),
+        ('\u{1f1b}', ['\u{1f13}', '\0', '\0']), ('\u{1f1c}', ['\u{1f14}', '\0', '\0']), ('\u{1f1d}',
+        ['\u{1f15}', '\0', '\0']), ('\u{1f28}', ['\u{1f20}', '\0', '\0']), ('\u{1f29}', ['\u{1f21}',
+        '\0', '\0']), ('\u{1f2a}', ['\u{1f22}', '\0', '\0']), ('\u{1f2b}', ['\u{1f23}', '\0',
+        '\0']), ('\u{1f2c}', ['\u{1f24}', '\0', '\0']), ('\u{1f2d}', ['\u{1f25}', '\0', '\0']),
+        ('\u{1f2e}', ['\u{1f26}', '\0', '\0']), ('\u{1f2f}', ['\u{1f27}', '\0', '\0']), ('\u{1f38}',
+        ['\u{1f30}', '\0', '\0']), ('\u{1f39}', ['\u{1f31}', '\0', '\0']), ('\u{1f3a}', ['\u{1f32}',
+        '\0', '\0']), ('\u{1f3b}', ['\u{1f33}', '\0', '\0']), ('\u{1f3c}', ['\u{1f34}', '\0',
+        '\0']), ('\u{1f3d}', ['\u{1f35}', '\0', '\0']), ('\u{1f3e}', ['\u{1f36}', '\0', '\0']),
+        ('\u{1f3f}', ['\u{1f37}', '\0', '\0']), ('\u{1f48}', ['\u{1f40}', '\0', '\0']), ('\u{1f49}',
+        ['\u{1f41}', '\0', '\0']), ('\u{1f4a}', ['\u{1f42}', '\0', '\0']), ('\u{1f4b}', ['\u{1f43}',
+        '\0', '\0']), ('\u{1f4c}', ['\u{1f44}', '\0', '\0']), ('\u{1f4d}', ['\u{1f45}', '\0',
+        '\0']), ('\u{1f59}', ['\u{1f51}', '\0', '\0']), ('\u{1f5b}', ['\u{1f53}', '\0', '\0']),
+        ('\u{1f5d}', ['\u{1f55}', '\0', '\0']), ('\u{1f5f}', ['\u{1f57}', '\0', '\0']), ('\u{1f68}',
+        ['\u{1f60}', '\0', '\0']), ('\u{1f69}', ['\u{1f61}', '\0', '\0']), ('\u{1f6a}', ['\u{1f62}',
+        '\0', '\0']), ('\u{1f6b}', ['\u{1f63}', '\0', '\0']), ('\u{1f6c}', ['\u{1f64}', '\0',
+        '\0']), ('\u{1f6d}', ['\u{1f65}', '\0', '\0']), ('\u{1f6e}', ['\u{1f66}', '\0', '\0']),
+        ('\u{1f6f}', ['\u{1f67}', '\0', '\0']), ('\u{1f88}', ['\u{1f80}', '\0', '\0']), ('\u{1f89}',
+        ['\u{1f81}', '\0', '\0']), ('\u{1f8a}', ['\u{1f82}', '\0', '\0']), ('\u{1f8b}', ['\u{1f83}',
+        '\0', '\0']), ('\u{1f8c}', ['\u{1f84}', '\0', '\0']), ('\u{1f8d}', ['\u{1f85}', '\0',
+        '\0']), ('\u{1f8e}', ['\u{1f86}', '\0', '\0']), ('\u{1f8f}', ['\u{1f87}', '\0', '\0']),
+        ('\u{1f98}', ['\u{1f90}', '\0', '\0']), ('\u{1f99}', ['\u{1f91}', '\0', '\0']), ('\u{1f9a}',
+        ['\u{1f92}', '\0', '\0']), ('\u{1f9b}', ['\u{1f93}', '\0', '\0']), ('\u{1f9c}', ['\u{1f94}',
+        '\0', '\0']), ('\u{1f9d}', ['\u{1f95}', '\0', '\0']), ('\u{1f9e}', ['\u{1f96}', '\0',
+        '\0']), ('\u{1f9f}', ['\u{1f97}', '\0', '\0']), ('\u{1fa8}', ['\u{1fa0}', '\0', '\0']),
+        ('\u{1fa9}', ['\u{1fa1}', '\0', '\0']), ('\u{1faa}', ['\u{1fa2}', '\0', '\0']), ('\u{1fab}',
+        ['\u{1fa3}', '\0', '\0']), ('\u{1fac}', ['\u{1fa4}', '\0', '\0']), ('\u{1fad}', ['\u{1fa5}',
+        '\0', '\0']), ('\u{1fae}', ['\u{1fa6}', '\0', '\0']), ('\u{1faf}', ['\u{1fa7}', '\0',
+        '\0']), ('\u{1fb8}', ['\u{1fb0}', '\0', '\0']), ('\u{1fb9}', ['\u{1fb1}', '\0', '\0']),
+        ('\u{1fba}', ['\u{1f70}', '\0', '\0']), ('\u{1fbb}', ['\u{1f71}', '\0', '\0']), ('\u{1fbc}',
+        ['\u{1fb3}', '\0', '\0']), ('\u{1fc8}', ['\u{1f72}', '\0', '\0']), ('\u{1fc9}', ['\u{1f73}',
+        '\0', '\0']), ('\u{1fca}', ['\u{1f74}', '\0', '\0']), ('\u{1fcb}', ['\u{1f75}', '\0',
+        '\0']), ('\u{1fcc}', ['\u{1fc3}', '\0', '\0']), ('\u{1fd8}', ['\u{1fd0}', '\0', '\0']),
+        ('\u{1fd9}', ['\u{1fd1}', '\0', '\0']), ('\u{1fda}', ['\u{1f76}', '\0', '\0']), ('\u{1fdb}',
+        ['\u{1f77}', '\0', '\0']), ('\u{1fe8}', ['\u{1fe0}', '\0', '\0']), ('\u{1fe9}', ['\u{1fe1}',
+        '\0', '\0']), ('\u{1fea}', ['\u{1f7a}', '\0', '\0']), ('\u{1feb}', ['\u{1f7b}', '\0',
+        '\0']), ('\u{1fec}', ['\u{1fe5}', '\0', '\0']), ('\u{1ff8}', ['\u{1f78}', '\0', '\0']),
+        ('\u{1ff9}', ['\u{1f79}', '\0', '\0']), ('\u{1ffa}', ['\u{1f7c}', '\0', '\0']), ('\u{1ffb}',
+        ['\u{1f7d}', '\0', '\0']), ('\u{1ffc}', ['\u{1ff3}', '\0', '\0']), ('\u{2126}', ['\u{3c9}',
+        '\0', '\0']), ('\u{212a}', ['\u{6b}', '\0', '\0']), ('\u{212b}', ['\u{e5}', '\0', '\0']),
+        ('\u{2132}', ['\u{214e}', '\0', '\0']), ('\u{2160}', ['\u{2170}', '\0', '\0']), ('\u{2161}',
+        ['\u{2171}', '\0', '\0']), ('\u{2162}', ['\u{2172}', '\0', '\0']), ('\u{2163}', ['\u{2173}',
+        '\0', '\0']), ('\u{2164}', ['\u{2174}', '\0', '\0']), ('\u{2165}', ['\u{2175}', '\0',
+        '\0']), ('\u{2166}', ['\u{2176}', '\0', '\0']), ('\u{2167}', ['\u{2177}', '\0', '\0']),
+        ('\u{2168}', ['\u{2178}', '\0', '\0']), ('\u{2169}', ['\u{2179}', '\0', '\0']), ('\u{216a}',
+        ['\u{217a}', '\0', '\0']), ('\u{216b}', ['\u{217b}', '\0', '\0']), ('\u{216c}', ['\u{217c}',
+        '\0', '\0']), ('\u{216d}', ['\u{217d}', '\0', '\0']), ('\u{216e}', ['\u{217e}', '\0',
+        '\0']), ('\u{216f}', ['\u{217f}', '\0', '\0']), ('\u{2183}', ['\u{2184}', '\0', '\0']),
+        ('\u{24b6}', ['\u{24d0}', '\0', '\0']), ('\u{24b7}', ['\u{24d1}', '\0', '\0']), ('\u{24b8}',
+        ['\u{24d2}', '\0', '\0']), ('\u{24b9}', ['\u{24d3}', '\0', '\0']), ('\u{24ba}', ['\u{24d4}',
+        '\0', '\0']), ('\u{24bb}', ['\u{24d5}', '\0', '\0']), ('\u{24bc}', ['\u{24d6}', '\0',
+        '\0']), ('\u{24bd}', ['\u{24d7}', '\0', '\0']), ('\u{24be}', ['\u{24d8}', '\0', '\0']),
+        ('\u{24bf}', ['\u{24d9}', '\0', '\0']), ('\u{24c0}', ['\u{24da}', '\0', '\0']), ('\u{24c1}',
+        ['\u{24db}', '\0', '\0']), ('\u{24c2}', ['\u{24dc}', '\0', '\0']), ('\u{24c3}', ['\u{24dd}',
+        '\0', '\0']), ('\u{24c4}', ['\u{24de}', '\0', '\0']), ('\u{24c5}', ['\u{24df}', '\0',
+        '\0']), ('\u{24c6}', ['\u{24e0}', '\0', '\0']), ('\u{24c7}', ['\u{24e1}', '\0', '\0']),
+        ('\u{24c8}', ['\u{24e2}', '\0', '\0']), ('\u{24c9}', ['\u{24e3}', '\0', '\0']), ('\u{24ca}',
+        ['\u{24e4}', '\0', '\0']), ('\u{24cb}', ['\u{24e5}', '\0', '\0']), ('\u{24cc}', ['\u{24e6}',
+        '\0', '\0']), ('\u{24cd}', ['\u{24e7}', '\0', '\0']), ('\u{24ce}', ['\u{24e8}', '\0',
+        '\0']), ('\u{24cf}', ['\u{24e9}', '\0', '\0']), ('\u{2c00}', ['\u{2c30}', '\0', '\0']),
+        ('\u{2c01}', ['\u{2c31}', '\0', '\0']), ('\u{2c02}', ['\u{2c32}', '\0', '\0']), ('\u{2c03}',
+        ['\u{2c33}', '\0', '\0']), ('\u{2c04}', ['\u{2c34}', '\0', '\0']), ('\u{2c05}', ['\u{2c35}',
+        '\0', '\0']), ('\u{2c06}', ['\u{2c36}', '\0', '\0']), ('\u{2c07}', ['\u{2c37}', '\0',
+        '\0']), ('\u{2c08}', ['\u{2c38}', '\0', '\0']), ('\u{2c09}', ['\u{2c39}', '\0', '\0']),
+        ('\u{2c0a}', ['\u{2c3a}', '\0', '\0']), ('\u{2c0b}', ['\u{2c3b}', '\0', '\0']), ('\u{2c0c}',
+        ['\u{2c3c}', '\0', '\0']), ('\u{2c0d}', ['\u{2c3d}', '\0', '\0']), ('\u{2c0e}', ['\u{2c3e}',
+        '\0', '\0']), ('\u{2c0f}', ['\u{2c3f}', '\0', '\0']), ('\u{2c10}', ['\u{2c40}', '\0',
+        '\0']), ('\u{2c11}', ['\u{2c41}', '\0', '\0']), ('\u{2c12}', ['\u{2c42}', '\0', '\0']),
+        ('\u{2c13}', ['\u{2c43}', '\0', '\0']), ('\u{2c14}', ['\u{2c44}', '\0', '\0']), ('\u{2c15}',
+        ['\u{2c45}', '\0', '\0']), ('\u{2c16}', ['\u{2c46}', '\0', '\0']), ('\u{2c17}', ['\u{2c47}',
+        '\0', '\0']), ('\u{2c18}', ['\u{2c48}', '\0', '\0']), ('\u{2c19}', ['\u{2c49}', '\0',
+        '\0']), ('\u{2c1a}', ['\u{2c4a}', '\0', '\0']), ('\u{2c1b}', ['\u{2c4b}', '\0', '\0']),
+        ('\u{2c1c}', ['\u{2c4c}', '\0', '\0']), ('\u{2c1d}', ['\u{2c4d}', '\0', '\0']), ('\u{2c1e}',
+        ['\u{2c4e}', '\0', '\0']), ('\u{2c1f}', ['\u{2c4f}', '\0', '\0']), ('\u{2c20}', ['\u{2c50}',
+        '\0', '\0']), ('\u{2c21}', ['\u{2c51}', '\0', '\0']), ('\u{2c22}', ['\u{2c52}', '\0',
+        '\0']), ('\u{2c23}', ['\u{2c53}', '\0', '\0']), ('\u{2c24}', ['\u{2c54}', '\0', '\0']),
+        ('\u{2c25}', ['\u{2c55}', '\0', '\0']), ('\u{2c26}', ['\u{2c56}', '\0', '\0']), ('\u{2c27}',
+        ['\u{2c57}', '\0', '\0']), ('\u{2c28}', ['\u{2c58}', '\0', '\0']), ('\u{2c29}', ['\u{2c59}',
+        '\0', '\0']), ('\u{2c2a}', ['\u{2c5a}', '\0', '\0']), ('\u{2c2b}', ['\u{2c5b}', '\0',
+        '\0']), ('\u{2c2c}', ['\u{2c5c}', '\0', '\0']), ('\u{2c2d}', ['\u{2c5d}', '\0', '\0']),
+        ('\u{2c2e}', ['\u{2c5e}', '\0', '\0']), ('\u{2c60}', ['\u{2c61}', '\0', '\0']), ('\u{2c62}',
+        ['\u{26b}', '\0', '\0']), ('\u{2c63}', ['\u{1d7d}', '\0', '\0']), ('\u{2c64}', ['\u{27d}',
+        '\0', '\0']), ('\u{2c67}', ['\u{2c68}', '\0', '\0']), ('\u{2c69}', ['\u{2c6a}', '\0',
+        '\0']), ('\u{2c6b}', ['\u{2c6c}', '\0', '\0']), ('\u{2c6d}', ['\u{251}', '\0', '\0']),
+        ('\u{2c6e}', ['\u{271}', '\0', '\0']), ('\u{2c6f}', ['\u{250}', '\0', '\0']), ('\u{2c70}',
+        ['\u{252}', '\0', '\0']), ('\u{2c72}', ['\u{2c73}', '\0', '\0']), ('\u{2c75}', ['\u{2c76}',
+        '\0', '\0']), ('\u{2c7e}', ['\u{23f}', '\0', '\0']), ('\u{2c7f}', ['\u{240}', '\0', '\0']),
+        ('\u{2c80}', ['\u{2c81}', '\0', '\0']), ('\u{2c82}', ['\u{2c83}', '\0', '\0']), ('\u{2c84}',
+        ['\u{2c85}', '\0', '\0']), ('\u{2c86}', ['\u{2c87}', '\0', '\0']), ('\u{2c88}', ['\u{2c89}',
+        '\0', '\0']), ('\u{2c8a}', ['\u{2c8b}', '\0', '\0']), ('\u{2c8c}', ['\u{2c8d}', '\0',
+        '\0']), ('\u{2c8e}', ['\u{2c8f}', '\0', '\0']), ('\u{2c90}', ['\u{2c91}', '\0', '\0']),
+        ('\u{2c92}', ['\u{2c93}', '\0', '\0']), ('\u{2c94}', ['\u{2c95}', '\0', '\0']), ('\u{2c96}',
+        ['\u{2c97}', '\0', '\0']), ('\u{2c98}', ['\u{2c99}', '\0', '\0']), ('\u{2c9a}', ['\u{2c9b}',
+        '\0', '\0']), ('\u{2c9c}', ['\u{2c9d}', '\0', '\0']), ('\u{2c9e}', ['\u{2c9f}', '\0',
+        '\0']), ('\u{2ca0}', ['\u{2ca1}', '\0', '\0']), ('\u{2ca2}', ['\u{2ca3}', '\0', '\0']),
+        ('\u{2ca4}', ['\u{2ca5}', '\0', '\0']), ('\u{2ca6}', ['\u{2ca7}', '\0', '\0']), ('\u{2ca8}',
+        ['\u{2ca9}', '\0', '\0']), ('\u{2caa}', ['\u{2cab}', '\0', '\0']), ('\u{2cac}', ['\u{2cad}',
+        '\0', '\0']), ('\u{2cae}', ['\u{2caf}', '\0', '\0']), ('\u{2cb0}', ['\u{2cb1}', '\0',
+        '\0']), ('\u{2cb2}', ['\u{2cb3}', '\0', '\0']), ('\u{2cb4}', ['\u{2cb5}', '\0', '\0']),
+        ('\u{2cb6}', ['\u{2cb7}', '\0', '\0']), ('\u{2cb8}', ['\u{2cb9}', '\0', '\0']), ('\u{2cba}',
+        ['\u{2cbb}', '\0', '\0']), ('\u{2cbc}', ['\u{2cbd}', '\0', '\0']), ('\u{2cbe}', ['\u{2cbf}',
+        '\0', '\0']), ('\u{2cc0}', ['\u{2cc1}', '\0', '\0']), ('\u{2cc2}', ['\u{2cc3}', '\0',
+        '\0']), ('\u{2cc4}', ['\u{2cc5}', '\0', '\0']), ('\u{2cc6}', ['\u{2cc7}', '\0', '\0']),
+        ('\u{2cc8}', ['\u{2cc9}', '\0', '\0']), ('\u{2cca}', ['\u{2ccb}', '\0', '\0']), ('\u{2ccc}',
+        ['\u{2ccd}', '\0', '\0']), ('\u{2cce}', ['\u{2ccf}', '\0', '\0']), ('\u{2cd0}', ['\u{2cd1}',
+        '\0', '\0']), ('\u{2cd2}', ['\u{2cd3}', '\0', '\0']), ('\u{2cd4}', ['\u{2cd5}', '\0',
+        '\0']), ('\u{2cd6}', ['\u{2cd7}', '\0', '\0']), ('\u{2cd8}', ['\u{2cd9}', '\0', '\0']),
+        ('\u{2cda}', ['\u{2cdb}', '\0', '\0']), ('\u{2cdc}', ['\u{2cdd}', '\0', '\0']), ('\u{2cde}',
+        ['\u{2cdf}', '\0', '\0']), ('\u{2ce0}', ['\u{2ce1}', '\0', '\0']), ('\u{2ce2}', ['\u{2ce3}',
+        '\0', '\0']), ('\u{2ceb}', ['\u{2cec}', '\0', '\0']), ('\u{2ced}', ['\u{2cee}', '\0',
+        '\0']), ('\u{2cf2}', ['\u{2cf3}', '\0', '\0']), ('\u{a640}', ['\u{a641}', '\0', '\0']),
+        ('\u{a642}', ['\u{a643}', '\0', '\0']), ('\u{a644}', ['\u{a645}', '\0', '\0']), ('\u{a646}',
+        ['\u{a647}', '\0', '\0']), ('\u{a648}', ['\u{a649}', '\0', '\0']), ('\u{a64a}', ['\u{a64b}',
+        '\0', '\0']), ('\u{a64c}', ['\u{a64d}', '\0', '\0']), ('\u{a64e}', ['\u{a64f}', '\0',
+        '\0']), ('\u{a650}', ['\u{a651}', '\0', '\0']), ('\u{a652}', ['\u{a653}', '\0', '\0']),
+        ('\u{a654}', ['\u{a655}', '\0', '\0']), ('\u{a656}', ['\u{a657}', '\0', '\0']), ('\u{a658}',
+        ['\u{a659}', '\0', '\0']), ('\u{a65a}', ['\u{a65b}', '\0', '\0']), ('\u{a65c}', ['\u{a65d}',
+        '\0', '\0']), ('\u{a65e}', ['\u{a65f}', '\0', '\0']), ('\u{a660}', ['\u{a661}', '\0',
+        '\0']), ('\u{a662}', ['\u{a663}', '\0', '\0']), ('\u{a664}', ['\u{a665}', '\0', '\0']),
+        ('\u{a666}', ['\u{a667}', '\0', '\0']), ('\u{a668}', ['\u{a669}', '\0', '\0']), ('\u{a66a}',
+        ['\u{a66b}', '\0', '\0']), ('\u{a66c}', ['\u{a66d}', '\0', '\0']), ('\u{a680}', ['\u{a681}',
+        '\0', '\0']), ('\u{a682}', ['\u{a683}', '\0', '\0']), ('\u{a684}', ['\u{a685}', '\0',
+        '\0']), ('\u{a686}', ['\u{a687}', '\0', '\0']), ('\u{a688}', ['\u{a689}', '\0', '\0']),
+        ('\u{a68a}', ['\u{a68b}', '\0', '\0']), ('\u{a68c}', ['\u{a68d}', '\0', '\0']), ('\u{a68e}',
+        ['\u{a68f}', '\0', '\0']), ('\u{a690}', ['\u{a691}', '\0', '\0']), ('\u{a692}', ['\u{a693}',
+        '\0', '\0']), ('\u{a694}', ['\u{a695}', '\0', '\0']), ('\u{a696}', ['\u{a697}', '\0',
+        '\0']), ('\u{a698}', ['\u{a699}', '\0', '\0']), ('\u{a69a}', ['\u{a69b}', '\0', '\0']),
+        ('\u{a722}', ['\u{a723}', '\0', '\0']), ('\u{a724}', ['\u{a725}', '\0', '\0']), ('\u{a726}',
+        ['\u{a727}', '\0', '\0']), ('\u{a728}', ['\u{a729}', '\0', '\0']), ('\u{a72a}', ['\u{a72b}',
+        '\0', '\0']), ('\u{a72c}', ['\u{a72d}', '\0', '\0']), ('\u{a72e}', ['\u{a72f}', '\0',
+        '\0']), ('\u{a732}', ['\u{a733}', '\0', '\0']), ('\u{a734}', ['\u{a735}', '\0', '\0']),
+        ('\u{a736}', ['\u{a737}', '\0', '\0']), ('\u{a738}', ['\u{a739}', '\0', '\0']), ('\u{a73a}',
+        ['\u{a73b}', '\0', '\0']), ('\u{a73c}', ['\u{a73d}', '\0', '\0']), ('\u{a73e}', ['\u{a73f}',
+        '\0', '\0']), ('\u{a740}', ['\u{a741}', '\0', '\0']), ('\u{a742}', ['\u{a743}', '\0',
+        '\0']), ('\u{a744}', ['\u{a745}', '\0', '\0']), ('\u{a746}', ['\u{a747}', '\0', '\0']),
+        ('\u{a748}', ['\u{a749}', '\0', '\0']), ('\u{a74a}', ['\u{a74b}', '\0', '\0']), ('\u{a74c}',
+        ['\u{a74d}', '\0', '\0']), ('\u{a74e}', ['\u{a74f}', '\0', '\0']), ('\u{a750}', ['\u{a751}',
+        '\0', '\0']), ('\u{a752}', ['\u{a753}', '\0', '\0']), ('\u{a754}', ['\u{a755}', '\0',
+        '\0']), ('\u{a756}', ['\u{a757}', '\0', '\0']), ('\u{a758}', ['\u{a759}', '\0', '\0']),
+        ('\u{a75a}', ['\u{a75b}', '\0', '\0']), ('\u{a75c}', ['\u{a75d}', '\0', '\0']), ('\u{a75e}',
+        ['\u{a75f}', '\0', '\0']), ('\u{a760}', ['\u{a761}', '\0', '\0']), ('\u{a762}', ['\u{a763}',
+        '\0', '\0']), ('\u{a764}', ['\u{a765}', '\0', '\0']), ('\u{a766}', ['\u{a767}', '\0',
+        '\0']), ('\u{a768}', ['\u{a769}', '\0', '\0']), ('\u{a76a}', ['\u{a76b}', '\0', '\0']),
+        ('\u{a76c}', ['\u{a76d}', '\0', '\0']), ('\u{a76e}', ['\u{a76f}', '\0', '\0']), ('\u{a779}',
+        ['\u{a77a}', '\0', '\0']), ('\u{a77b}', ['\u{a77c}', '\0', '\0']), ('\u{a77d}', ['\u{1d79}',
+        '\0', '\0']), ('\u{a77e}', ['\u{a77f}', '\0', '\0']), ('\u{a780}', ['\u{a781}', '\0',
+        '\0']), ('\u{a782}', ['\u{a783}', '\0', '\0']), ('\u{a784}', ['\u{a785}', '\0', '\0']),
+        ('\u{a786}', ['\u{a787}', '\0', '\0']), ('\u{a78b}', ['\u{a78c}', '\0', '\0']), ('\u{a78d}',
+        ['\u{265}', '\0', '\0']), ('\u{a790}', ['\u{a791}', '\0', '\0']), ('\u{a792}', ['\u{a793}',
+        '\0', '\0']), ('\u{a796}', ['\u{a797}', '\0', '\0']), ('\u{a798}', ['\u{a799}', '\0',
+        '\0']), ('\u{a79a}', ['\u{a79b}', '\0', '\0']), ('\u{a79c}', ['\u{a79d}', '\0', '\0']),
+        ('\u{a79e}', ['\u{a79f}', '\0', '\0']), ('\u{a7a0}', ['\u{a7a1}', '\0', '\0']), ('\u{a7a2}',
+        ['\u{a7a3}', '\0', '\0']), ('\u{a7a4}', ['\u{a7a5}', '\0', '\0']), ('\u{a7a6}', ['\u{a7a7}',
+        '\0', '\0']), ('\u{a7a8}', ['\u{a7a9}', '\0', '\0']), ('\u{a7aa}', ['\u{266}', '\0', '\0']),
+        ('\u{a7ab}', ['\u{25c}', '\0', '\0']), ('\u{a7ac}', ['\u{261}', '\0', '\0']), ('\u{a7ad}',
+        ['\u{26c}', '\0', '\0']), ('\u{a7ae}', ['\u{26a}', '\0', '\0']), ('\u{a7b0}', ['\u{29e}',
+        '\0', '\0']), ('\u{a7b1}', ['\u{287}', '\0', '\0']), ('\u{a7b2}', ['\u{29d}', '\0', '\0']),
+        ('\u{a7b3}', ['\u{ab53}', '\0', '\0']), ('\u{a7b4}', ['\u{a7b5}', '\0', '\0']), ('\u{a7b6}',
+        ['\u{a7b7}', '\0', '\0']), ('\u{a7b8}', ['\u{a7b9}', '\0', '\0']), ('\u{ff21}', ['\u{ff41}',
+        '\0', '\0']), ('\u{ff22}', ['\u{ff42}', '\0', '\0']), ('\u{ff23}', ['\u{ff43}', '\0',
+        '\0']), ('\u{ff24}', ['\u{ff44}', '\0', '\0']), ('\u{ff25}', ['\u{ff45}', '\0', '\0']),
+        ('\u{ff26}', ['\u{ff46}', '\0', '\0']), ('\u{ff27}', ['\u{ff47}', '\0', '\0']), ('\u{ff28}',
+        ['\u{ff48}', '\0', '\0']), ('\u{ff29}', ['\u{ff49}', '\0', '\0']), ('\u{ff2a}', ['\u{ff4a}',
+        '\0', '\0']), ('\u{ff2b}', ['\u{ff4b}', '\0', '\0']), ('\u{ff2c}', ['\u{ff4c}', '\0',
+        '\0']), ('\u{ff2d}', ['\u{ff4d}', '\0', '\0']), ('\u{ff2e}', ['\u{ff4e}', '\0', '\0']),
+        ('\u{ff2f}', ['\u{ff4f}', '\0', '\0']), ('\u{ff30}', ['\u{ff50}', '\0', '\0']), ('\u{ff31}',
+        ['\u{ff51}', '\0', '\0']), ('\u{ff32}', ['\u{ff52}', '\0', '\0']), ('\u{ff33}', ['\u{ff53}',
+        '\0', '\0']), ('\u{ff34}', ['\u{ff54}', '\0', '\0']), ('\u{ff35}', ['\u{ff55}', '\0',
+        '\0']), ('\u{ff36}', ['\u{ff56}', '\0', '\0']), ('\u{ff37}', ['\u{ff57}', '\0', '\0']),
+        ('\u{ff38}', ['\u{ff58}', '\0', '\0']), ('\u{ff39}', ['\u{ff59}', '\0', '\0']), ('\u{ff3a}',
+        ['\u{ff5a}', '\0', '\0']), ('\u{10400}', ['\u{10428}', '\0', '\0']), ('\u{10401}',
+        ['\u{10429}', '\0', '\0']), ('\u{10402}', ['\u{1042a}', '\0', '\0']), ('\u{10403}',
+        ['\u{1042b}', '\0', '\0']), ('\u{10404}', ['\u{1042c}', '\0', '\0']), ('\u{10405}',
+        ['\u{1042d}', '\0', '\0']), ('\u{10406}', ['\u{1042e}', '\0', '\0']), ('\u{10407}',
+        ['\u{1042f}', '\0', '\0']), ('\u{10408}', ['\u{10430}', '\0', '\0']), ('\u{10409}',
+        ['\u{10431}', '\0', '\0']), ('\u{1040a}', ['\u{10432}', '\0', '\0']), ('\u{1040b}',
+        ['\u{10433}', '\0', '\0']), ('\u{1040c}', ['\u{10434}', '\0', '\0']), ('\u{1040d}',
+        ['\u{10435}', '\0', '\0']), ('\u{1040e}', ['\u{10436}', '\0', '\0']), ('\u{1040f}',
+        ['\u{10437}', '\0', '\0']), ('\u{10410}', ['\u{10438}', '\0', '\0']), ('\u{10411}',
+        ['\u{10439}', '\0', '\0']), ('\u{10412}', ['\u{1043a}', '\0', '\0']), ('\u{10413}',
+        ['\u{1043b}', '\0', '\0']), ('\u{10414}', ['\u{1043c}', '\0', '\0']), ('\u{10415}',
+        ['\u{1043d}', '\0', '\0']), ('\u{10416}', ['\u{1043e}', '\0', '\0']), ('\u{10417}',
+        ['\u{1043f}', '\0', '\0']), ('\u{10418}', ['\u{10440}', '\0', '\0']), ('\u{10419}',
+        ['\u{10441}', '\0', '\0']), ('\u{1041a}', ['\u{10442}', '\0', '\0']), ('\u{1041b}',
+        ['\u{10443}', '\0', '\0']), ('\u{1041c}', ['\u{10444}', '\0', '\0']), ('\u{1041d}',
+        ['\u{10445}', '\0', '\0']), ('\u{1041e}', ['\u{10446}', '\0', '\0']), ('\u{1041f}',
+        ['\u{10447}', '\0', '\0']), ('\u{10420}', ['\u{10448}', '\0', '\0']), ('\u{10421}',
+        ['\u{10449}', '\0', '\0']), ('\u{10422}', ['\u{1044a}', '\0', '\0']), ('\u{10423}',
+        ['\u{1044b}', '\0', '\0']), ('\u{10424}', ['\u{1044c}', '\0', '\0']), ('\u{10425}',
+        ['\u{1044d}', '\0', '\0']), ('\u{10426}', ['\u{1044e}', '\0', '\0']), ('\u{10427}',
+        ['\u{1044f}', '\0', '\0']), ('\u{104b0}', ['\u{104d8}', '\0', '\0']), ('\u{104b1}',
+        ['\u{104d9}', '\0', '\0']), ('\u{104b2}', ['\u{104da}', '\0', '\0']), ('\u{104b3}',
+        ['\u{104db}', '\0', '\0']), ('\u{104b4}', ['\u{104dc}', '\0', '\0']), ('\u{104b5}',
+        ['\u{104dd}', '\0', '\0']), ('\u{104b6}', ['\u{104de}', '\0', '\0']), ('\u{104b7}',
+        ['\u{104df}', '\0', '\0']), ('\u{104b8}', ['\u{104e0}', '\0', '\0']), ('\u{104b9}',
+        ['\u{104e1}', '\0', '\0']), ('\u{104ba}', ['\u{104e2}', '\0', '\0']), ('\u{104bb}',
+        ['\u{104e3}', '\0', '\0']), ('\u{104bc}', ['\u{104e4}', '\0', '\0']), ('\u{104bd}',
+        ['\u{104e5}', '\0', '\0']), ('\u{104be}', ['\u{104e6}', '\0', '\0']), ('\u{104bf}',
+        ['\u{104e7}', '\0', '\0']), ('\u{104c0}', ['\u{104e8}', '\0', '\0']), ('\u{104c1}',
+        ['\u{104e9}', '\0', '\0']), ('\u{104c2}', ['\u{104ea}', '\0', '\0']), ('\u{104c3}',
+        ['\u{104eb}', '\0', '\0']), ('\u{104c4}', ['\u{104ec}', '\0', '\0']), ('\u{104c5}',
+        ['\u{104ed}', '\0', '\0']), ('\u{104c6}', ['\u{104ee}', '\0', '\0']), ('\u{104c7}',
+        ['\u{104ef}', '\0', '\0']), ('\u{104c8}', ['\u{104f0}', '\0', '\0']), ('\u{104c9}',
+        ['\u{104f1}', '\0', '\0']), ('\u{104ca}', ['\u{104f2}', '\0', '\0']), ('\u{104cb}',
+        ['\u{104f3}', '\0', '\0']), ('\u{104cc}', ['\u{104f4}', '\0', '\0']), ('\u{104cd}',
+        ['\u{104f5}', '\0', '\0']), ('\u{104ce}', ['\u{104f6}', '\0', '\0']), ('\u{104cf}',
+        ['\u{104f7}', '\0', '\0']), ('\u{104d0}', ['\u{104f8}', '\0', '\0']), ('\u{104d1}',
+        ['\u{104f9}', '\0', '\0']), ('\u{104d2}', ['\u{104fa}', '\0', '\0']), ('\u{104d3}',
+        ['\u{104fb}', '\0', '\0']), ('\u{10c80}', ['\u{10cc0}', '\0', '\0']), ('\u{10c81}',
+        ['\u{10cc1}', '\0', '\0']), ('\u{10c82}', ['\u{10cc2}', '\0', '\0']), ('\u{10c83}',
+        ['\u{10cc3}', '\0', '\0']), ('\u{10c84}', ['\u{10cc4}', '\0', '\0']), ('\u{10c85}',
+        ['\u{10cc5}', '\0', '\0']), ('\u{10c86}', ['\u{10cc6}', '\0', '\0']), ('\u{10c87}',
+        ['\u{10cc7}', '\0', '\0']), ('\u{10c88}', ['\u{10cc8}', '\0', '\0']), ('\u{10c89}',
+        ['\u{10cc9}', '\0', '\0']), ('\u{10c8a}', ['\u{10cca}', '\0', '\0']), ('\u{10c8b}',
+        ['\u{10ccb}', '\0', '\0']), ('\u{10c8c}', ['\u{10ccc}', '\0', '\0']), ('\u{10c8d}',
+        ['\u{10ccd}', '\0', '\0']), ('\u{10c8e}', ['\u{10cce}', '\0', '\0']), ('\u{10c8f}',
+        ['\u{10ccf}', '\0', '\0']), ('\u{10c90}', ['\u{10cd0}', '\0', '\0']), ('\u{10c91}',
+        ['\u{10cd1}', '\0', '\0']), ('\u{10c92}', ['\u{10cd2}', '\0', '\0']), ('\u{10c93}',
+        ['\u{10cd3}', '\0', '\0']), ('\u{10c94}', ['\u{10cd4}', '\0', '\0']), ('\u{10c95}',
+        ['\u{10cd5}', '\0', '\0']), ('\u{10c96}', ['\u{10cd6}', '\0', '\0']), ('\u{10c97}',
+        ['\u{10cd7}', '\0', '\0']), ('\u{10c98}', ['\u{10cd8}', '\0', '\0']), ('\u{10c99}',
+        ['\u{10cd9}', '\0', '\0']), ('\u{10c9a}', ['\u{10cda}', '\0', '\0']), ('\u{10c9b}',
+        ['\u{10cdb}', '\0', '\0']), ('\u{10c9c}', ['\u{10cdc}', '\0', '\0']), ('\u{10c9d}',
+        ['\u{10cdd}', '\0', '\0']), ('\u{10c9e}', ['\u{10cde}', '\0', '\0']), ('\u{10c9f}',
+        ['\u{10cdf}', '\0', '\0']), ('\u{10ca0}', ['\u{10ce0}', '\0', '\0']), ('\u{10ca1}',
+        ['\u{10ce1}', '\0', '\0']), ('\u{10ca2}', ['\u{10ce2}', '\0', '\0']), ('\u{10ca3}',
+        ['\u{10ce3}', '\0', '\0']), ('\u{10ca4}', ['\u{10ce4}', '\0', '\0']), ('\u{10ca5}',
+        ['\u{10ce5}', '\0', '\0']), ('\u{10ca6}', ['\u{10ce6}', '\0', '\0']), ('\u{10ca7}',
+        ['\u{10ce7}', '\0', '\0']), ('\u{10ca8}', ['\u{10ce8}', '\0', '\0']), ('\u{10ca9}',
+        ['\u{10ce9}', '\0', '\0']), ('\u{10caa}', ['\u{10cea}', '\0', '\0']), ('\u{10cab}',
+        ['\u{10ceb}', '\0', '\0']), ('\u{10cac}', ['\u{10cec}', '\0', '\0']), ('\u{10cad}',
+        ['\u{10ced}', '\0', '\0']), ('\u{10cae}', ['\u{10cee}', '\0', '\0']), ('\u{10caf}',
+        ['\u{10cef}', '\0', '\0']), ('\u{10cb0}', ['\u{10cf0}', '\0', '\0']), ('\u{10cb1}',
+        ['\u{10cf1}', '\0', '\0']), ('\u{10cb2}', ['\u{10cf2}', '\0', '\0']), ('\u{118a0}',
+        ['\u{118c0}', '\0', '\0']), ('\u{118a1}', ['\u{118c1}', '\0', '\0']), ('\u{118a2}',
+        ['\u{118c2}', '\0', '\0']), ('\u{118a3}', ['\u{118c3}', '\0', '\0']), ('\u{118a4}',
+        ['\u{118c4}', '\0', '\0']), ('\u{118a5}', ['\u{118c5}', '\0', '\0']), ('\u{118a6}',
+        ['\u{118c6}', '\0', '\0']), ('\u{118a7}', ['\u{118c7}', '\0', '\0']), ('\u{118a8}',
+        ['\u{118c8}', '\0', '\0']), ('\u{118a9}', ['\u{118c9}', '\0', '\0']), ('\u{118aa}',
+        ['\u{118ca}', '\0', '\0']), ('\u{118ab}', ['\u{118cb}', '\0', '\0']), ('\u{118ac}',
+        ['\u{118cc}', '\0', '\0']), ('\u{118ad}', ['\u{118cd}', '\0', '\0']), ('\u{118ae}',
+        ['\u{118ce}', '\0', '\0']), ('\u{118af}', ['\u{118cf}', '\0', '\0']), ('\u{118b0}',
+        ['\u{118d0}', '\0', '\0']), ('\u{118b1}', ['\u{118d1}', '\0', '\0']), ('\u{118b2}',
+        ['\u{118d2}', '\0', '\0']), ('\u{118b3}', ['\u{118d3}', '\0', '\0']), ('\u{118b4}',
+        ['\u{118d4}', '\0', '\0']), ('\u{118b5}', ['\u{118d5}', '\0', '\0']), ('\u{118b6}',
+        ['\u{118d6}', '\0', '\0']), ('\u{118b7}', ['\u{118d7}', '\0', '\0']), ('\u{118b8}',
+        ['\u{118d8}', '\0', '\0']), ('\u{118b9}', ['\u{118d9}', '\0', '\0']), ('\u{118ba}',
+        ['\u{118da}', '\0', '\0']), ('\u{118bb}', ['\u{118db}', '\0', '\0']), ('\u{118bc}',
+        ['\u{118dc}', '\0', '\0']), ('\u{118bd}', ['\u{118dd}', '\0', '\0']), ('\u{118be}',
+        ['\u{118de}', '\0', '\0']), ('\u{118bf}', ['\u{118df}', '\0', '\0']), ('\u{16e40}',
+        ['\u{16e60}', '\0', '\0']), ('\u{16e41}', ['\u{16e61}', '\0', '\0']), ('\u{16e42}',
+        ['\u{16e62}', '\0', '\0']), ('\u{16e43}', ['\u{16e63}', '\0', '\0']), ('\u{16e44}',
+        ['\u{16e64}', '\0', '\0']), ('\u{16e45}', ['\u{16e65}', '\0', '\0']), ('\u{16e46}',
+        ['\u{16e66}', '\0', '\0']), ('\u{16e47}', ['\u{16e67}', '\0', '\0']), ('\u{16e48}',
+        ['\u{16e68}', '\0', '\0']), ('\u{16e49}', ['\u{16e69}', '\0', '\0']), ('\u{16e4a}',
+        ['\u{16e6a}', '\0', '\0']), ('\u{16e4b}', ['\u{16e6b}', '\0', '\0']), ('\u{16e4c}',
+        ['\u{16e6c}', '\0', '\0']), ('\u{16e4d}', ['\u{16e6d}', '\0', '\0']), ('\u{16e4e}',
+        ['\u{16e6e}', '\0', '\0']), ('\u{16e4f}', ['\u{16e6f}', '\0', '\0']), ('\u{16e50}',
+        ['\u{16e70}', '\0', '\0']), ('\u{16e51}', ['\u{16e71}', '\0', '\0']), ('\u{16e52}',
+        ['\u{16e72}', '\0', '\0']), ('\u{16e53}', ['\u{16e73}', '\0', '\0']), ('\u{16e54}',
+        ['\u{16e74}', '\0', '\0']), ('\u{16e55}', ['\u{16e75}', '\0', '\0']), ('\u{16e56}',
+        ['\u{16e76}', '\0', '\0']), ('\u{16e57}', ['\u{16e77}', '\0', '\0']), ('\u{16e58}',
+        ['\u{16e78}', '\0', '\0']), ('\u{16e59}', ['\u{16e79}', '\0', '\0']), ('\u{16e5a}',
+        ['\u{16e7a}', '\0', '\0']), ('\u{16e5b}', ['\u{16e7b}', '\0', '\0']), ('\u{16e5c}',
+        ['\u{16e7c}', '\0', '\0']), ('\u{16e5d}', ['\u{16e7d}', '\0', '\0']), ('\u{16e5e}',
+        ['\u{16e7e}', '\0', '\0']), ('\u{16e5f}', ['\u{16e7f}', '\0', '\0']), ('\u{1e900}',
+        ['\u{1e922}', '\0', '\0']), ('\u{1e901}', ['\u{1e923}', '\0', '\0']), ('\u{1e902}',
+        ['\u{1e924}', '\0', '\0']), ('\u{1e903}', ['\u{1e925}', '\0', '\0']), ('\u{1e904}',
+        ['\u{1e926}', '\0', '\0']), ('\u{1e905}', ['\u{1e927}', '\0', '\0']), ('\u{1e906}',
+        ['\u{1e928}', '\0', '\0']), ('\u{1e907}', ['\u{1e929}', '\0', '\0']), ('\u{1e908}',
+        ['\u{1e92a}', '\0', '\0']), ('\u{1e909}', ['\u{1e92b}', '\0', '\0']), ('\u{1e90a}',
+        ['\u{1e92c}', '\0', '\0']), ('\u{1e90b}', ['\u{1e92d}', '\0', '\0']), ('\u{1e90c}',
+        ['\u{1e92e}', '\0', '\0']), ('\u{1e90d}', ['\u{1e92f}', '\0', '\0']), ('\u{1e90e}',
+        ['\u{1e930}', '\0', '\0']), ('\u{1e90f}', ['\u{1e931}', '\0', '\0']), ('\u{1e910}',
+        ['\u{1e932}', '\0', '\0']), ('\u{1e911}', ['\u{1e933}', '\0', '\0']), ('\u{1e912}',
+        ['\u{1e934}', '\0', '\0']), ('\u{1e913}', ['\u{1e935}', '\0', '\0']), ('\u{1e914}',
+        ['\u{1e936}', '\0', '\0']), ('\u{1e915}', ['\u{1e937}', '\0', '\0']), ('\u{1e916}',
+        ['\u{1e938}', '\0', '\0']), ('\u{1e917}', ['\u{1e939}', '\0', '\0']), ('\u{1e918}',
+        ['\u{1e93a}', '\0', '\0']), ('\u{1e919}', ['\u{1e93b}', '\0', '\0']), ('\u{1e91a}',
+        ['\u{1e93c}', '\0', '\0']), ('\u{1e91b}', ['\u{1e93d}', '\0', '\0']), ('\u{1e91c}',
+        ['\u{1e93e}', '\0', '\0']), ('\u{1e91d}', ['\u{1e93f}', '\0', '\0']), ('\u{1e91e}',
+        ['\u{1e940}', '\0', '\0']), ('\u{1e91f}', ['\u{1e941}', '\0', '\0']), ('\u{1e920}',
+        ['\u{1e942}', '\0', '\0']), ('\u{1e921}', ['\u{1e943}', '\0', '\0'])
     ];
 
     const to_uppercase_table: &[(char, [char; 3])] = &[
@@ -2076,325 +2129,346 @@
         ['\u{550}', '\0', '\0']), ('\u{581}', ['\u{551}', '\0', '\0']), ('\u{582}', ['\u{552}',
         '\0', '\0']), ('\u{583}', ['\u{553}', '\0', '\0']), ('\u{584}', ['\u{554}', '\0', '\0']),
         ('\u{585}', ['\u{555}', '\0', '\0']), ('\u{586}', ['\u{556}', '\0', '\0']), ('\u{587}',
-        ['\u{535}', '\u{552}', '\0']), ('\u{13f8}', ['\u{13f0}', '\0', '\0']), ('\u{13f9}',
-        ['\u{13f1}', '\0', '\0']), ('\u{13fa}', ['\u{13f2}', '\0', '\0']), ('\u{13fb}', ['\u{13f3}',
-        '\0', '\0']), ('\u{13fc}', ['\u{13f4}', '\0', '\0']), ('\u{13fd}', ['\u{13f5}', '\0',
-        '\0']), ('\u{1c80}', ['\u{412}', '\0', '\0']), ('\u{1c81}', ['\u{414}', '\0', '\0']),
-        ('\u{1c82}', ['\u{41e}', '\0', '\0']), ('\u{1c83}', ['\u{421}', '\0', '\0']), ('\u{1c84}',
-        ['\u{422}', '\0', '\0']), ('\u{1c85}', ['\u{422}', '\0', '\0']), ('\u{1c86}', ['\u{42a}',
-        '\0', '\0']), ('\u{1c87}', ['\u{462}', '\0', '\0']), ('\u{1c88}', ['\u{a64a}', '\0', '\0']),
-        ('\u{1d79}', ['\u{a77d}', '\0', '\0']), ('\u{1d7d}', ['\u{2c63}', '\0', '\0']), ('\u{1e01}',
-        ['\u{1e00}', '\0', '\0']), ('\u{1e03}', ['\u{1e02}', '\0', '\0']), ('\u{1e05}', ['\u{1e04}',
-        '\0', '\0']), ('\u{1e07}', ['\u{1e06}', '\0', '\0']), ('\u{1e09}', ['\u{1e08}', '\0',
-        '\0']), ('\u{1e0b}', ['\u{1e0a}', '\0', '\0']), ('\u{1e0d}', ['\u{1e0c}', '\0', '\0']),
-        ('\u{1e0f}', ['\u{1e0e}', '\0', '\0']), ('\u{1e11}', ['\u{1e10}', '\0', '\0']), ('\u{1e13}',
-        ['\u{1e12}', '\0', '\0']), ('\u{1e15}', ['\u{1e14}', '\0', '\0']), ('\u{1e17}', ['\u{1e16}',
-        '\0', '\0']), ('\u{1e19}', ['\u{1e18}', '\0', '\0']), ('\u{1e1b}', ['\u{1e1a}', '\0',
-        '\0']), ('\u{1e1d}', ['\u{1e1c}', '\0', '\0']), ('\u{1e1f}', ['\u{1e1e}', '\0', '\0']),
-        ('\u{1e21}', ['\u{1e20}', '\0', '\0']), ('\u{1e23}', ['\u{1e22}', '\0', '\0']), ('\u{1e25}',
-        ['\u{1e24}', '\0', '\0']), ('\u{1e27}', ['\u{1e26}', '\0', '\0']), ('\u{1e29}', ['\u{1e28}',
-        '\0', '\0']), ('\u{1e2b}', ['\u{1e2a}', '\0', '\0']), ('\u{1e2d}', ['\u{1e2c}', '\0',
-        '\0']), ('\u{1e2f}', ['\u{1e2e}', '\0', '\0']), ('\u{1e31}', ['\u{1e30}', '\0', '\0']),
-        ('\u{1e33}', ['\u{1e32}', '\0', '\0']), ('\u{1e35}', ['\u{1e34}', '\0', '\0']), ('\u{1e37}',
-        ['\u{1e36}', '\0', '\0']), ('\u{1e39}', ['\u{1e38}', '\0', '\0']), ('\u{1e3b}', ['\u{1e3a}',
-        '\0', '\0']), ('\u{1e3d}', ['\u{1e3c}', '\0', '\0']), ('\u{1e3f}', ['\u{1e3e}', '\0',
-        '\0']), ('\u{1e41}', ['\u{1e40}', '\0', '\0']), ('\u{1e43}', ['\u{1e42}', '\0', '\0']),
-        ('\u{1e45}', ['\u{1e44}', '\0', '\0']), ('\u{1e47}', ['\u{1e46}', '\0', '\0']), ('\u{1e49}',
-        ['\u{1e48}', '\0', '\0']), ('\u{1e4b}', ['\u{1e4a}', '\0', '\0']), ('\u{1e4d}', ['\u{1e4c}',
-        '\0', '\0']), ('\u{1e4f}', ['\u{1e4e}', '\0', '\0']), ('\u{1e51}', ['\u{1e50}', '\0',
-        '\0']), ('\u{1e53}', ['\u{1e52}', '\0', '\0']), ('\u{1e55}', ['\u{1e54}', '\0', '\0']),
-        ('\u{1e57}', ['\u{1e56}', '\0', '\0']), ('\u{1e59}', ['\u{1e58}', '\0', '\0']), ('\u{1e5b}',
-        ['\u{1e5a}', '\0', '\0']), ('\u{1e5d}', ['\u{1e5c}', '\0', '\0']), ('\u{1e5f}', ['\u{1e5e}',
-        '\0', '\0']), ('\u{1e61}', ['\u{1e60}', '\0', '\0']), ('\u{1e63}', ['\u{1e62}', '\0',
-        '\0']), ('\u{1e65}', ['\u{1e64}', '\0', '\0']), ('\u{1e67}', ['\u{1e66}', '\0', '\0']),
-        ('\u{1e69}', ['\u{1e68}', '\0', '\0']), ('\u{1e6b}', ['\u{1e6a}', '\0', '\0']), ('\u{1e6d}',
-        ['\u{1e6c}', '\0', '\0']), ('\u{1e6f}', ['\u{1e6e}', '\0', '\0']), ('\u{1e71}', ['\u{1e70}',
-        '\0', '\0']), ('\u{1e73}', ['\u{1e72}', '\0', '\0']), ('\u{1e75}', ['\u{1e74}', '\0',
-        '\0']), ('\u{1e77}', ['\u{1e76}', '\0', '\0']), ('\u{1e79}', ['\u{1e78}', '\0', '\0']),
-        ('\u{1e7b}', ['\u{1e7a}', '\0', '\0']), ('\u{1e7d}', ['\u{1e7c}', '\0', '\0']), ('\u{1e7f}',
-        ['\u{1e7e}', '\0', '\0']), ('\u{1e81}', ['\u{1e80}', '\0', '\0']), ('\u{1e83}', ['\u{1e82}',
-        '\0', '\0']), ('\u{1e85}', ['\u{1e84}', '\0', '\0']), ('\u{1e87}', ['\u{1e86}', '\0',
-        '\0']), ('\u{1e89}', ['\u{1e88}', '\0', '\0']), ('\u{1e8b}', ['\u{1e8a}', '\0', '\0']),
-        ('\u{1e8d}', ['\u{1e8c}', '\0', '\0']), ('\u{1e8f}', ['\u{1e8e}', '\0', '\0']), ('\u{1e91}',
-        ['\u{1e90}', '\0', '\0']), ('\u{1e93}', ['\u{1e92}', '\0', '\0']), ('\u{1e95}', ['\u{1e94}',
-        '\0', '\0']), ('\u{1e96}', ['\u{48}', '\u{331}', '\0']), ('\u{1e97}', ['\u{54}', '\u{308}',
-        '\0']), ('\u{1e98}', ['\u{57}', '\u{30a}', '\0']), ('\u{1e99}', ['\u{59}', '\u{30a}',
-        '\0']), ('\u{1e9a}', ['\u{41}', '\u{2be}', '\0']), ('\u{1e9b}', ['\u{1e60}', '\0', '\0']),
-        ('\u{1ea1}', ['\u{1ea0}', '\0', '\0']), ('\u{1ea3}', ['\u{1ea2}', '\0', '\0']), ('\u{1ea5}',
-        ['\u{1ea4}', '\0', '\0']), ('\u{1ea7}', ['\u{1ea6}', '\0', '\0']), ('\u{1ea9}', ['\u{1ea8}',
-        '\0', '\0']), ('\u{1eab}', ['\u{1eaa}', '\0', '\0']), ('\u{1ead}', ['\u{1eac}', '\0',
-        '\0']), ('\u{1eaf}', ['\u{1eae}', '\0', '\0']), ('\u{1eb1}', ['\u{1eb0}', '\0', '\0']),
-        ('\u{1eb3}', ['\u{1eb2}', '\0', '\0']), ('\u{1eb5}', ['\u{1eb4}', '\0', '\0']), ('\u{1eb7}',
-        ['\u{1eb6}', '\0', '\0']), ('\u{1eb9}', ['\u{1eb8}', '\0', '\0']), ('\u{1ebb}', ['\u{1eba}',
-        '\0', '\0']), ('\u{1ebd}', ['\u{1ebc}', '\0', '\0']), ('\u{1ebf}', ['\u{1ebe}', '\0',
-        '\0']), ('\u{1ec1}', ['\u{1ec0}', '\0', '\0']), ('\u{1ec3}', ['\u{1ec2}', '\0', '\0']),
-        ('\u{1ec5}', ['\u{1ec4}', '\0', '\0']), ('\u{1ec7}', ['\u{1ec6}', '\0', '\0']), ('\u{1ec9}',
-        ['\u{1ec8}', '\0', '\0']), ('\u{1ecb}', ['\u{1eca}', '\0', '\0']), ('\u{1ecd}', ['\u{1ecc}',
-        '\0', '\0']), ('\u{1ecf}', ['\u{1ece}', '\0', '\0']), ('\u{1ed1}', ['\u{1ed0}', '\0',
-        '\0']), ('\u{1ed3}', ['\u{1ed2}', '\0', '\0']), ('\u{1ed5}', ['\u{1ed4}', '\0', '\0']),
-        ('\u{1ed7}', ['\u{1ed6}', '\0', '\0']), ('\u{1ed9}', ['\u{1ed8}', '\0', '\0']), ('\u{1edb}',
-        ['\u{1eda}', '\0', '\0']), ('\u{1edd}', ['\u{1edc}', '\0', '\0']), ('\u{1edf}', ['\u{1ede}',
-        '\0', '\0']), ('\u{1ee1}', ['\u{1ee0}', '\0', '\0']), ('\u{1ee3}', ['\u{1ee2}', '\0',
-        '\0']), ('\u{1ee5}', ['\u{1ee4}', '\0', '\0']), ('\u{1ee7}', ['\u{1ee6}', '\0', '\0']),
-        ('\u{1ee9}', ['\u{1ee8}', '\0', '\0']), ('\u{1eeb}', ['\u{1eea}', '\0', '\0']), ('\u{1eed}',
-        ['\u{1eec}', '\0', '\0']), ('\u{1eef}', ['\u{1eee}', '\0', '\0']), ('\u{1ef1}', ['\u{1ef0}',
-        '\0', '\0']), ('\u{1ef3}', ['\u{1ef2}', '\0', '\0']), ('\u{1ef5}', ['\u{1ef4}', '\0',
-        '\0']), ('\u{1ef7}', ['\u{1ef6}', '\0', '\0']), ('\u{1ef9}', ['\u{1ef8}', '\0', '\0']),
-        ('\u{1efb}', ['\u{1efa}', '\0', '\0']), ('\u{1efd}', ['\u{1efc}', '\0', '\0']), ('\u{1eff}',
-        ['\u{1efe}', '\0', '\0']), ('\u{1f00}', ['\u{1f08}', '\0', '\0']), ('\u{1f01}', ['\u{1f09}',
-        '\0', '\0']), ('\u{1f02}', ['\u{1f0a}', '\0', '\0']), ('\u{1f03}', ['\u{1f0b}', '\0',
-        '\0']), ('\u{1f04}', ['\u{1f0c}', '\0', '\0']), ('\u{1f05}', ['\u{1f0d}', '\0', '\0']),
-        ('\u{1f06}', ['\u{1f0e}', '\0', '\0']), ('\u{1f07}', ['\u{1f0f}', '\0', '\0']), ('\u{1f10}',
-        ['\u{1f18}', '\0', '\0']), ('\u{1f11}', ['\u{1f19}', '\0', '\0']), ('\u{1f12}', ['\u{1f1a}',
-        '\0', '\0']), ('\u{1f13}', ['\u{1f1b}', '\0', '\0']), ('\u{1f14}', ['\u{1f1c}', '\0',
-        '\0']), ('\u{1f15}', ['\u{1f1d}', '\0', '\0']), ('\u{1f20}', ['\u{1f28}', '\0', '\0']),
-        ('\u{1f21}', ['\u{1f29}', '\0', '\0']), ('\u{1f22}', ['\u{1f2a}', '\0', '\0']), ('\u{1f23}',
-        ['\u{1f2b}', '\0', '\0']), ('\u{1f24}', ['\u{1f2c}', '\0', '\0']), ('\u{1f25}', ['\u{1f2d}',
-        '\0', '\0']), ('\u{1f26}', ['\u{1f2e}', '\0', '\0']), ('\u{1f27}', ['\u{1f2f}', '\0',
-        '\0']), ('\u{1f30}', ['\u{1f38}', '\0', '\0']), ('\u{1f31}', ['\u{1f39}', '\0', '\0']),
-        ('\u{1f32}', ['\u{1f3a}', '\0', '\0']), ('\u{1f33}', ['\u{1f3b}', '\0', '\0']), ('\u{1f34}',
-        ['\u{1f3c}', '\0', '\0']), ('\u{1f35}', ['\u{1f3d}', '\0', '\0']), ('\u{1f36}', ['\u{1f3e}',
-        '\0', '\0']), ('\u{1f37}', ['\u{1f3f}', '\0', '\0']), ('\u{1f40}', ['\u{1f48}', '\0',
-        '\0']), ('\u{1f41}', ['\u{1f49}', '\0', '\0']), ('\u{1f42}', ['\u{1f4a}', '\0', '\0']),
-        ('\u{1f43}', ['\u{1f4b}', '\0', '\0']), ('\u{1f44}', ['\u{1f4c}', '\0', '\0']), ('\u{1f45}',
-        ['\u{1f4d}', '\0', '\0']), ('\u{1f50}', ['\u{3a5}', '\u{313}', '\0']), ('\u{1f51}',
-        ['\u{1f59}', '\0', '\0']), ('\u{1f52}', ['\u{3a5}', '\u{313}', '\u{300}']), ('\u{1f53}',
-        ['\u{1f5b}', '\0', '\0']), ('\u{1f54}', ['\u{3a5}', '\u{313}', '\u{301}']), ('\u{1f55}',
-        ['\u{1f5d}', '\0', '\0']), ('\u{1f56}', ['\u{3a5}', '\u{313}', '\u{342}']), ('\u{1f57}',
-        ['\u{1f5f}', '\0', '\0']), ('\u{1f60}', ['\u{1f68}', '\0', '\0']), ('\u{1f61}', ['\u{1f69}',
-        '\0', '\0']), ('\u{1f62}', ['\u{1f6a}', '\0', '\0']), ('\u{1f63}', ['\u{1f6b}', '\0',
-        '\0']), ('\u{1f64}', ['\u{1f6c}', '\0', '\0']), ('\u{1f65}', ['\u{1f6d}', '\0', '\0']),
-        ('\u{1f66}', ['\u{1f6e}', '\0', '\0']), ('\u{1f67}', ['\u{1f6f}', '\0', '\0']), ('\u{1f70}',
-        ['\u{1fba}', '\0', '\0']), ('\u{1f71}', ['\u{1fbb}', '\0', '\0']), ('\u{1f72}', ['\u{1fc8}',
-        '\0', '\0']), ('\u{1f73}', ['\u{1fc9}', '\0', '\0']), ('\u{1f74}', ['\u{1fca}', '\0',
-        '\0']), ('\u{1f75}', ['\u{1fcb}', '\0', '\0']), ('\u{1f76}', ['\u{1fda}', '\0', '\0']),
-        ('\u{1f77}', ['\u{1fdb}', '\0', '\0']), ('\u{1f78}', ['\u{1ff8}', '\0', '\0']), ('\u{1f79}',
-        ['\u{1ff9}', '\0', '\0']), ('\u{1f7a}', ['\u{1fea}', '\0', '\0']), ('\u{1f7b}', ['\u{1feb}',
-        '\0', '\0']), ('\u{1f7c}', ['\u{1ffa}', '\0', '\0']), ('\u{1f7d}', ['\u{1ffb}', '\0',
-        '\0']), ('\u{1f80}', ['\u{1f08}', '\u{399}', '\0']), ('\u{1f81}', ['\u{1f09}', '\u{399}',
-        '\0']), ('\u{1f82}', ['\u{1f0a}', '\u{399}', '\0']), ('\u{1f83}', ['\u{1f0b}', '\u{399}',
-        '\0']), ('\u{1f84}', ['\u{1f0c}', '\u{399}', '\0']), ('\u{1f85}', ['\u{1f0d}', '\u{399}',
-        '\0']), ('\u{1f86}', ['\u{1f0e}', '\u{399}', '\0']), ('\u{1f87}', ['\u{1f0f}', '\u{399}',
-        '\0']), ('\u{1f88}', ['\u{1f08}', '\u{399}', '\0']), ('\u{1f89}', ['\u{1f09}', '\u{399}',
-        '\0']), ('\u{1f8a}', ['\u{1f0a}', '\u{399}', '\0']), ('\u{1f8b}', ['\u{1f0b}', '\u{399}',
-        '\0']), ('\u{1f8c}', ['\u{1f0c}', '\u{399}', '\0']), ('\u{1f8d}', ['\u{1f0d}', '\u{399}',
-        '\0']), ('\u{1f8e}', ['\u{1f0e}', '\u{399}', '\0']), ('\u{1f8f}', ['\u{1f0f}', '\u{399}',
-        '\0']), ('\u{1f90}', ['\u{1f28}', '\u{399}', '\0']), ('\u{1f91}', ['\u{1f29}', '\u{399}',
-        '\0']), ('\u{1f92}', ['\u{1f2a}', '\u{399}', '\0']), ('\u{1f93}', ['\u{1f2b}', '\u{399}',
-        '\0']), ('\u{1f94}', ['\u{1f2c}', '\u{399}', '\0']), ('\u{1f95}', ['\u{1f2d}', '\u{399}',
-        '\0']), ('\u{1f96}', ['\u{1f2e}', '\u{399}', '\0']), ('\u{1f97}', ['\u{1f2f}', '\u{399}',
-        '\0']), ('\u{1f98}', ['\u{1f28}', '\u{399}', '\0']), ('\u{1f99}', ['\u{1f29}', '\u{399}',
-        '\0']), ('\u{1f9a}', ['\u{1f2a}', '\u{399}', '\0']), ('\u{1f9b}', ['\u{1f2b}', '\u{399}',
-        '\0']), ('\u{1f9c}', ['\u{1f2c}', '\u{399}', '\0']), ('\u{1f9d}', ['\u{1f2d}', '\u{399}',
-        '\0']), ('\u{1f9e}', ['\u{1f2e}', '\u{399}', '\0']), ('\u{1f9f}', ['\u{1f2f}', '\u{399}',
-        '\0']), ('\u{1fa0}', ['\u{1f68}', '\u{399}', '\0']), ('\u{1fa1}', ['\u{1f69}', '\u{399}',
-        '\0']), ('\u{1fa2}', ['\u{1f6a}', '\u{399}', '\0']), ('\u{1fa3}', ['\u{1f6b}', '\u{399}',
-        '\0']), ('\u{1fa4}', ['\u{1f6c}', '\u{399}', '\0']), ('\u{1fa5}', ['\u{1f6d}', '\u{399}',
-        '\0']), ('\u{1fa6}', ['\u{1f6e}', '\u{399}', '\0']), ('\u{1fa7}', ['\u{1f6f}', '\u{399}',
-        '\0']), ('\u{1fa8}', ['\u{1f68}', '\u{399}', '\0']), ('\u{1fa9}', ['\u{1f69}', '\u{399}',
-        '\0']), ('\u{1faa}', ['\u{1f6a}', '\u{399}', '\0']), ('\u{1fab}', ['\u{1f6b}', '\u{399}',
-        '\0']), ('\u{1fac}', ['\u{1f6c}', '\u{399}', '\0']), ('\u{1fad}', ['\u{1f6d}', '\u{399}',
-        '\0']), ('\u{1fae}', ['\u{1f6e}', '\u{399}', '\0']), ('\u{1faf}', ['\u{1f6f}', '\u{399}',
-        '\0']), ('\u{1fb0}', ['\u{1fb8}', '\0', '\0']), ('\u{1fb1}', ['\u{1fb9}', '\0', '\0']),
-        ('\u{1fb2}', ['\u{1fba}', '\u{399}', '\0']), ('\u{1fb3}', ['\u{391}', '\u{399}', '\0']),
-        ('\u{1fb4}', ['\u{386}', '\u{399}', '\0']), ('\u{1fb6}', ['\u{391}', '\u{342}', '\0']),
-        ('\u{1fb7}', ['\u{391}', '\u{342}', '\u{399}']), ('\u{1fbc}', ['\u{391}', '\u{399}', '\0']),
-        ('\u{1fbe}', ['\u{399}', '\0', '\0']), ('\u{1fc2}', ['\u{1fca}', '\u{399}', '\0']),
-        ('\u{1fc3}', ['\u{397}', '\u{399}', '\0']), ('\u{1fc4}', ['\u{389}', '\u{399}', '\0']),
-        ('\u{1fc6}', ['\u{397}', '\u{342}', '\0']), ('\u{1fc7}', ['\u{397}', '\u{342}', '\u{399}']),
-        ('\u{1fcc}', ['\u{397}', '\u{399}', '\0']), ('\u{1fd0}', ['\u{1fd8}', '\0', '\0']),
-        ('\u{1fd1}', ['\u{1fd9}', '\0', '\0']), ('\u{1fd2}', ['\u{399}', '\u{308}', '\u{300}']),
-        ('\u{1fd3}', ['\u{399}', '\u{308}', '\u{301}']), ('\u{1fd6}', ['\u{399}', '\u{342}', '\0']),
-        ('\u{1fd7}', ['\u{399}', '\u{308}', '\u{342}']), ('\u{1fe0}', ['\u{1fe8}', '\0', '\0']),
-        ('\u{1fe1}', ['\u{1fe9}', '\0', '\0']), ('\u{1fe2}', ['\u{3a5}', '\u{308}', '\u{300}']),
-        ('\u{1fe3}', ['\u{3a5}', '\u{308}', '\u{301}']), ('\u{1fe4}', ['\u{3a1}', '\u{313}', '\0']),
-        ('\u{1fe5}', ['\u{1fec}', '\0', '\0']), ('\u{1fe6}', ['\u{3a5}', '\u{342}', '\0']),
-        ('\u{1fe7}', ['\u{3a5}', '\u{308}', '\u{342}']), ('\u{1ff2}', ['\u{1ffa}', '\u{399}',
-        '\0']), ('\u{1ff3}', ['\u{3a9}', '\u{399}', '\0']), ('\u{1ff4}', ['\u{38f}', '\u{399}',
-        '\0']), ('\u{1ff6}', ['\u{3a9}', '\u{342}', '\0']), ('\u{1ff7}', ['\u{3a9}', '\u{342}',
-        '\u{399}']), ('\u{1ffc}', ['\u{3a9}', '\u{399}', '\0']), ('\u{214e}', ['\u{2132}', '\0',
-        '\0']), ('\u{2170}', ['\u{2160}', '\0', '\0']), ('\u{2171}', ['\u{2161}', '\0', '\0']),
-        ('\u{2172}', ['\u{2162}', '\0', '\0']), ('\u{2173}', ['\u{2163}', '\0', '\0']), ('\u{2174}',
-        ['\u{2164}', '\0', '\0']), ('\u{2175}', ['\u{2165}', '\0', '\0']), ('\u{2176}', ['\u{2166}',
-        '\0', '\0']), ('\u{2177}', ['\u{2167}', '\0', '\0']), ('\u{2178}', ['\u{2168}', '\0',
-        '\0']), ('\u{2179}', ['\u{2169}', '\0', '\0']), ('\u{217a}', ['\u{216a}', '\0', '\0']),
-        ('\u{217b}', ['\u{216b}', '\0', '\0']), ('\u{217c}', ['\u{216c}', '\0', '\0']), ('\u{217d}',
-        ['\u{216d}', '\0', '\0']), ('\u{217e}', ['\u{216e}', '\0', '\0']), ('\u{217f}', ['\u{216f}',
-        '\0', '\0']), ('\u{2184}', ['\u{2183}', '\0', '\0']), ('\u{24d0}', ['\u{24b6}', '\0',
-        '\0']), ('\u{24d1}', ['\u{24b7}', '\0', '\0']), ('\u{24d2}', ['\u{24b8}', '\0', '\0']),
-        ('\u{24d3}', ['\u{24b9}', '\0', '\0']), ('\u{24d4}', ['\u{24ba}', '\0', '\0']), ('\u{24d5}',
-        ['\u{24bb}', '\0', '\0']), ('\u{24d6}', ['\u{24bc}', '\0', '\0']), ('\u{24d7}', ['\u{24bd}',
-        '\0', '\0']), ('\u{24d8}', ['\u{24be}', '\0', '\0']), ('\u{24d9}', ['\u{24bf}', '\0',
-        '\0']), ('\u{24da}', ['\u{24c0}', '\0', '\0']), ('\u{24db}', ['\u{24c1}', '\0', '\0']),
-        ('\u{24dc}', ['\u{24c2}', '\0', '\0']), ('\u{24dd}', ['\u{24c3}', '\0', '\0']), ('\u{24de}',
-        ['\u{24c4}', '\0', '\0']), ('\u{24df}', ['\u{24c5}', '\0', '\0']), ('\u{24e0}', ['\u{24c6}',
-        '\0', '\0']), ('\u{24e1}', ['\u{24c7}', '\0', '\0']), ('\u{24e2}', ['\u{24c8}', '\0',
-        '\0']), ('\u{24e3}', ['\u{24c9}', '\0', '\0']), ('\u{24e4}', ['\u{24ca}', '\0', '\0']),
-        ('\u{24e5}', ['\u{24cb}', '\0', '\0']), ('\u{24e6}', ['\u{24cc}', '\0', '\0']), ('\u{24e7}',
-        ['\u{24cd}', '\0', '\0']), ('\u{24e8}', ['\u{24ce}', '\0', '\0']), ('\u{24e9}', ['\u{24cf}',
-        '\0', '\0']), ('\u{2c30}', ['\u{2c00}', '\0', '\0']), ('\u{2c31}', ['\u{2c01}', '\0',
-        '\0']), ('\u{2c32}', ['\u{2c02}', '\0', '\0']), ('\u{2c33}', ['\u{2c03}', '\0', '\0']),
-        ('\u{2c34}', ['\u{2c04}', '\0', '\0']), ('\u{2c35}', ['\u{2c05}', '\0', '\0']), ('\u{2c36}',
-        ['\u{2c06}', '\0', '\0']), ('\u{2c37}', ['\u{2c07}', '\0', '\0']), ('\u{2c38}', ['\u{2c08}',
-        '\0', '\0']), ('\u{2c39}', ['\u{2c09}', '\0', '\0']), ('\u{2c3a}', ['\u{2c0a}', '\0',
-        '\0']), ('\u{2c3b}', ['\u{2c0b}', '\0', '\0']), ('\u{2c3c}', ['\u{2c0c}', '\0', '\0']),
-        ('\u{2c3d}', ['\u{2c0d}', '\0', '\0']), ('\u{2c3e}', ['\u{2c0e}', '\0', '\0']), ('\u{2c3f}',
-        ['\u{2c0f}', '\0', '\0']), ('\u{2c40}', ['\u{2c10}', '\0', '\0']), ('\u{2c41}', ['\u{2c11}',
-        '\0', '\0']), ('\u{2c42}', ['\u{2c12}', '\0', '\0']), ('\u{2c43}', ['\u{2c13}', '\0',
-        '\0']), ('\u{2c44}', ['\u{2c14}', '\0', '\0']), ('\u{2c45}', ['\u{2c15}', '\0', '\0']),
-        ('\u{2c46}', ['\u{2c16}', '\0', '\0']), ('\u{2c47}', ['\u{2c17}', '\0', '\0']), ('\u{2c48}',
-        ['\u{2c18}', '\0', '\0']), ('\u{2c49}', ['\u{2c19}', '\0', '\0']), ('\u{2c4a}', ['\u{2c1a}',
-        '\0', '\0']), ('\u{2c4b}', ['\u{2c1b}', '\0', '\0']), ('\u{2c4c}', ['\u{2c1c}', '\0',
-        '\0']), ('\u{2c4d}', ['\u{2c1d}', '\0', '\0']), ('\u{2c4e}', ['\u{2c1e}', '\0', '\0']),
-        ('\u{2c4f}', ['\u{2c1f}', '\0', '\0']), ('\u{2c50}', ['\u{2c20}', '\0', '\0']), ('\u{2c51}',
-        ['\u{2c21}', '\0', '\0']), ('\u{2c52}', ['\u{2c22}', '\0', '\0']), ('\u{2c53}', ['\u{2c23}',
-        '\0', '\0']), ('\u{2c54}', ['\u{2c24}', '\0', '\0']), ('\u{2c55}', ['\u{2c25}', '\0',
-        '\0']), ('\u{2c56}', ['\u{2c26}', '\0', '\0']), ('\u{2c57}', ['\u{2c27}', '\0', '\0']),
-        ('\u{2c58}', ['\u{2c28}', '\0', '\0']), ('\u{2c59}', ['\u{2c29}', '\0', '\0']), ('\u{2c5a}',
-        ['\u{2c2a}', '\0', '\0']), ('\u{2c5b}', ['\u{2c2b}', '\0', '\0']), ('\u{2c5c}', ['\u{2c2c}',
-        '\0', '\0']), ('\u{2c5d}', ['\u{2c2d}', '\0', '\0']), ('\u{2c5e}', ['\u{2c2e}', '\0',
-        '\0']), ('\u{2c61}', ['\u{2c60}', '\0', '\0']), ('\u{2c65}', ['\u{23a}', '\0', '\0']),
-        ('\u{2c66}', ['\u{23e}', '\0', '\0']), ('\u{2c68}', ['\u{2c67}', '\0', '\0']), ('\u{2c6a}',
-        ['\u{2c69}', '\0', '\0']), ('\u{2c6c}', ['\u{2c6b}', '\0', '\0']), ('\u{2c73}', ['\u{2c72}',
-        '\0', '\0']), ('\u{2c76}', ['\u{2c75}', '\0', '\0']), ('\u{2c81}', ['\u{2c80}', '\0',
-        '\0']), ('\u{2c83}', ['\u{2c82}', '\0', '\0']), ('\u{2c85}', ['\u{2c84}', '\0', '\0']),
-        ('\u{2c87}', ['\u{2c86}', '\0', '\0']), ('\u{2c89}', ['\u{2c88}', '\0', '\0']), ('\u{2c8b}',
-        ['\u{2c8a}', '\0', '\0']), ('\u{2c8d}', ['\u{2c8c}', '\0', '\0']), ('\u{2c8f}', ['\u{2c8e}',
-        '\0', '\0']), ('\u{2c91}', ['\u{2c90}', '\0', '\0']), ('\u{2c93}', ['\u{2c92}', '\0',
-        '\0']), ('\u{2c95}', ['\u{2c94}', '\0', '\0']), ('\u{2c97}', ['\u{2c96}', '\0', '\0']),
-        ('\u{2c99}', ['\u{2c98}', '\0', '\0']), ('\u{2c9b}', ['\u{2c9a}', '\0', '\0']), ('\u{2c9d}',
-        ['\u{2c9c}', '\0', '\0']), ('\u{2c9f}', ['\u{2c9e}', '\0', '\0']), ('\u{2ca1}', ['\u{2ca0}',
-        '\0', '\0']), ('\u{2ca3}', ['\u{2ca2}', '\0', '\0']), ('\u{2ca5}', ['\u{2ca4}', '\0',
-        '\0']), ('\u{2ca7}', ['\u{2ca6}', '\0', '\0']), ('\u{2ca9}', ['\u{2ca8}', '\0', '\0']),
-        ('\u{2cab}', ['\u{2caa}', '\0', '\0']), ('\u{2cad}', ['\u{2cac}', '\0', '\0']), ('\u{2caf}',
-        ['\u{2cae}', '\0', '\0']), ('\u{2cb1}', ['\u{2cb0}', '\0', '\0']), ('\u{2cb3}', ['\u{2cb2}',
-        '\0', '\0']), ('\u{2cb5}', ['\u{2cb4}', '\0', '\0']), ('\u{2cb7}', ['\u{2cb6}', '\0',
-        '\0']), ('\u{2cb9}', ['\u{2cb8}', '\0', '\0']), ('\u{2cbb}', ['\u{2cba}', '\0', '\0']),
-        ('\u{2cbd}', ['\u{2cbc}', '\0', '\0']), ('\u{2cbf}', ['\u{2cbe}', '\0', '\0']), ('\u{2cc1}',
-        ['\u{2cc0}', '\0', '\0']), ('\u{2cc3}', ['\u{2cc2}', '\0', '\0']), ('\u{2cc5}', ['\u{2cc4}',
-        '\0', '\0']), ('\u{2cc7}', ['\u{2cc6}', '\0', '\0']), ('\u{2cc9}', ['\u{2cc8}', '\0',
-        '\0']), ('\u{2ccb}', ['\u{2cca}', '\0', '\0']), ('\u{2ccd}', ['\u{2ccc}', '\0', '\0']),
-        ('\u{2ccf}', ['\u{2cce}', '\0', '\0']), ('\u{2cd1}', ['\u{2cd0}', '\0', '\0']), ('\u{2cd3}',
-        ['\u{2cd2}', '\0', '\0']), ('\u{2cd5}', ['\u{2cd4}', '\0', '\0']), ('\u{2cd7}', ['\u{2cd6}',
-        '\0', '\0']), ('\u{2cd9}', ['\u{2cd8}', '\0', '\0']), ('\u{2cdb}', ['\u{2cda}', '\0',
-        '\0']), ('\u{2cdd}', ['\u{2cdc}', '\0', '\0']), ('\u{2cdf}', ['\u{2cde}', '\0', '\0']),
-        ('\u{2ce1}', ['\u{2ce0}', '\0', '\0']), ('\u{2ce3}', ['\u{2ce2}', '\0', '\0']), ('\u{2cec}',
-        ['\u{2ceb}', '\0', '\0']), ('\u{2cee}', ['\u{2ced}', '\0', '\0']), ('\u{2cf3}', ['\u{2cf2}',
-        '\0', '\0']), ('\u{2d00}', ['\u{10a0}', '\0', '\0']), ('\u{2d01}', ['\u{10a1}', '\0',
-        '\0']), ('\u{2d02}', ['\u{10a2}', '\0', '\0']), ('\u{2d03}', ['\u{10a3}', '\0', '\0']),
-        ('\u{2d04}', ['\u{10a4}', '\0', '\0']), ('\u{2d05}', ['\u{10a5}', '\0', '\0']), ('\u{2d06}',
-        ['\u{10a6}', '\0', '\0']), ('\u{2d07}', ['\u{10a7}', '\0', '\0']), ('\u{2d08}', ['\u{10a8}',
-        '\0', '\0']), ('\u{2d09}', ['\u{10a9}', '\0', '\0']), ('\u{2d0a}', ['\u{10aa}', '\0',
-        '\0']), ('\u{2d0b}', ['\u{10ab}', '\0', '\0']), ('\u{2d0c}', ['\u{10ac}', '\0', '\0']),
-        ('\u{2d0d}', ['\u{10ad}', '\0', '\0']), ('\u{2d0e}', ['\u{10ae}', '\0', '\0']), ('\u{2d0f}',
-        ['\u{10af}', '\0', '\0']), ('\u{2d10}', ['\u{10b0}', '\0', '\0']), ('\u{2d11}', ['\u{10b1}',
-        '\0', '\0']), ('\u{2d12}', ['\u{10b2}', '\0', '\0']), ('\u{2d13}', ['\u{10b3}', '\0',
-        '\0']), ('\u{2d14}', ['\u{10b4}', '\0', '\0']), ('\u{2d15}', ['\u{10b5}', '\0', '\0']),
-        ('\u{2d16}', ['\u{10b6}', '\0', '\0']), ('\u{2d17}', ['\u{10b7}', '\0', '\0']), ('\u{2d18}',
-        ['\u{10b8}', '\0', '\0']), ('\u{2d19}', ['\u{10b9}', '\0', '\0']), ('\u{2d1a}', ['\u{10ba}',
-        '\0', '\0']), ('\u{2d1b}', ['\u{10bb}', '\0', '\0']), ('\u{2d1c}', ['\u{10bc}', '\0',
-        '\0']), ('\u{2d1d}', ['\u{10bd}', '\0', '\0']), ('\u{2d1e}', ['\u{10be}', '\0', '\0']),
-        ('\u{2d1f}', ['\u{10bf}', '\0', '\0']), ('\u{2d20}', ['\u{10c0}', '\0', '\0']), ('\u{2d21}',
-        ['\u{10c1}', '\0', '\0']), ('\u{2d22}', ['\u{10c2}', '\0', '\0']), ('\u{2d23}', ['\u{10c3}',
-        '\0', '\0']), ('\u{2d24}', ['\u{10c4}', '\0', '\0']), ('\u{2d25}', ['\u{10c5}', '\0',
-        '\0']), ('\u{2d27}', ['\u{10c7}', '\0', '\0']), ('\u{2d2d}', ['\u{10cd}', '\0', '\0']),
-        ('\u{a641}', ['\u{a640}', '\0', '\0']), ('\u{a643}', ['\u{a642}', '\0', '\0']), ('\u{a645}',
-        ['\u{a644}', '\0', '\0']), ('\u{a647}', ['\u{a646}', '\0', '\0']), ('\u{a649}', ['\u{a648}',
-        '\0', '\0']), ('\u{a64b}', ['\u{a64a}', '\0', '\0']), ('\u{a64d}', ['\u{a64c}', '\0',
-        '\0']), ('\u{a64f}', ['\u{a64e}', '\0', '\0']), ('\u{a651}', ['\u{a650}', '\0', '\0']),
-        ('\u{a653}', ['\u{a652}', '\0', '\0']), ('\u{a655}', ['\u{a654}', '\0', '\0']), ('\u{a657}',
-        ['\u{a656}', '\0', '\0']), ('\u{a659}', ['\u{a658}', '\0', '\0']), ('\u{a65b}', ['\u{a65a}',
-        '\0', '\0']), ('\u{a65d}', ['\u{a65c}', '\0', '\0']), ('\u{a65f}', ['\u{a65e}', '\0',
-        '\0']), ('\u{a661}', ['\u{a660}', '\0', '\0']), ('\u{a663}', ['\u{a662}', '\0', '\0']),
-        ('\u{a665}', ['\u{a664}', '\0', '\0']), ('\u{a667}', ['\u{a666}', '\0', '\0']), ('\u{a669}',
-        ['\u{a668}', '\0', '\0']), ('\u{a66b}', ['\u{a66a}', '\0', '\0']), ('\u{a66d}', ['\u{a66c}',
-        '\0', '\0']), ('\u{a681}', ['\u{a680}', '\0', '\0']), ('\u{a683}', ['\u{a682}', '\0',
-        '\0']), ('\u{a685}', ['\u{a684}', '\0', '\0']), ('\u{a687}', ['\u{a686}', '\0', '\0']),
-        ('\u{a689}', ['\u{a688}', '\0', '\0']), ('\u{a68b}', ['\u{a68a}', '\0', '\0']), ('\u{a68d}',
-        ['\u{a68c}', '\0', '\0']), ('\u{a68f}', ['\u{a68e}', '\0', '\0']), ('\u{a691}', ['\u{a690}',
-        '\0', '\0']), ('\u{a693}', ['\u{a692}', '\0', '\0']), ('\u{a695}', ['\u{a694}', '\0',
-        '\0']), ('\u{a697}', ['\u{a696}', '\0', '\0']), ('\u{a699}', ['\u{a698}', '\0', '\0']),
-        ('\u{a69b}', ['\u{a69a}', '\0', '\0']), ('\u{a723}', ['\u{a722}', '\0', '\0']), ('\u{a725}',
-        ['\u{a724}', '\0', '\0']), ('\u{a727}', ['\u{a726}', '\0', '\0']), ('\u{a729}', ['\u{a728}',
-        '\0', '\0']), ('\u{a72b}', ['\u{a72a}', '\0', '\0']), ('\u{a72d}', ['\u{a72c}', '\0',
-        '\0']), ('\u{a72f}', ['\u{a72e}', '\0', '\0']), ('\u{a733}', ['\u{a732}', '\0', '\0']),
-        ('\u{a735}', ['\u{a734}', '\0', '\0']), ('\u{a737}', ['\u{a736}', '\0', '\0']), ('\u{a739}',
-        ['\u{a738}', '\0', '\0']), ('\u{a73b}', ['\u{a73a}', '\0', '\0']), ('\u{a73d}', ['\u{a73c}',
-        '\0', '\0']), ('\u{a73f}', ['\u{a73e}', '\0', '\0']), ('\u{a741}', ['\u{a740}', '\0',
-        '\0']), ('\u{a743}', ['\u{a742}', '\0', '\0']), ('\u{a745}', ['\u{a744}', '\0', '\0']),
-        ('\u{a747}', ['\u{a746}', '\0', '\0']), ('\u{a749}', ['\u{a748}', '\0', '\0']), ('\u{a74b}',
-        ['\u{a74a}', '\0', '\0']), ('\u{a74d}', ['\u{a74c}', '\0', '\0']), ('\u{a74f}', ['\u{a74e}',
-        '\0', '\0']), ('\u{a751}', ['\u{a750}', '\0', '\0']), ('\u{a753}', ['\u{a752}', '\0',
-        '\0']), ('\u{a755}', ['\u{a754}', '\0', '\0']), ('\u{a757}', ['\u{a756}', '\0', '\0']),
-        ('\u{a759}', ['\u{a758}', '\0', '\0']), ('\u{a75b}', ['\u{a75a}', '\0', '\0']), ('\u{a75d}',
-        ['\u{a75c}', '\0', '\0']), ('\u{a75f}', ['\u{a75e}', '\0', '\0']), ('\u{a761}', ['\u{a760}',
-        '\0', '\0']), ('\u{a763}', ['\u{a762}', '\0', '\0']), ('\u{a765}', ['\u{a764}', '\0',
-        '\0']), ('\u{a767}', ['\u{a766}', '\0', '\0']), ('\u{a769}', ['\u{a768}', '\0', '\0']),
-        ('\u{a76b}', ['\u{a76a}', '\0', '\0']), ('\u{a76d}', ['\u{a76c}', '\0', '\0']), ('\u{a76f}',
-        ['\u{a76e}', '\0', '\0']), ('\u{a77a}', ['\u{a779}', '\0', '\0']), ('\u{a77c}', ['\u{a77b}',
-        '\0', '\0']), ('\u{a77f}', ['\u{a77e}', '\0', '\0']), ('\u{a781}', ['\u{a780}', '\0',
-        '\0']), ('\u{a783}', ['\u{a782}', '\0', '\0']), ('\u{a785}', ['\u{a784}', '\0', '\0']),
-        ('\u{a787}', ['\u{a786}', '\0', '\0']), ('\u{a78c}', ['\u{a78b}', '\0', '\0']), ('\u{a791}',
-        ['\u{a790}', '\0', '\0']), ('\u{a793}', ['\u{a792}', '\0', '\0']), ('\u{a797}', ['\u{a796}',
-        '\0', '\0']), ('\u{a799}', ['\u{a798}', '\0', '\0']), ('\u{a79b}', ['\u{a79a}', '\0',
-        '\0']), ('\u{a79d}', ['\u{a79c}', '\0', '\0']), ('\u{a79f}', ['\u{a79e}', '\0', '\0']),
-        ('\u{a7a1}', ['\u{a7a0}', '\0', '\0']), ('\u{a7a3}', ['\u{a7a2}', '\0', '\0']), ('\u{a7a5}',
-        ['\u{a7a4}', '\0', '\0']), ('\u{a7a7}', ['\u{a7a6}', '\0', '\0']), ('\u{a7a9}', ['\u{a7a8}',
-        '\0', '\0']), ('\u{a7b5}', ['\u{a7b4}', '\0', '\0']), ('\u{a7b7}', ['\u{a7b6}', '\0',
-        '\0']), ('\u{ab53}', ['\u{a7b3}', '\0', '\0']), ('\u{ab70}', ['\u{13a0}', '\0', '\0']),
-        ('\u{ab71}', ['\u{13a1}', '\0', '\0']), ('\u{ab72}', ['\u{13a2}', '\0', '\0']), ('\u{ab73}',
-        ['\u{13a3}', '\0', '\0']), ('\u{ab74}', ['\u{13a4}', '\0', '\0']), ('\u{ab75}', ['\u{13a5}',
-        '\0', '\0']), ('\u{ab76}', ['\u{13a6}', '\0', '\0']), ('\u{ab77}', ['\u{13a7}', '\0',
-        '\0']), ('\u{ab78}', ['\u{13a8}', '\0', '\0']), ('\u{ab79}', ['\u{13a9}', '\0', '\0']),
-        ('\u{ab7a}', ['\u{13aa}', '\0', '\0']), ('\u{ab7b}', ['\u{13ab}', '\0', '\0']), ('\u{ab7c}',
-        ['\u{13ac}', '\0', '\0']), ('\u{ab7d}', ['\u{13ad}', '\0', '\0']), ('\u{ab7e}', ['\u{13ae}',
-        '\0', '\0']), ('\u{ab7f}', ['\u{13af}', '\0', '\0']), ('\u{ab80}', ['\u{13b0}', '\0',
-        '\0']), ('\u{ab81}', ['\u{13b1}', '\0', '\0']), ('\u{ab82}', ['\u{13b2}', '\0', '\0']),
-        ('\u{ab83}', ['\u{13b3}', '\0', '\0']), ('\u{ab84}', ['\u{13b4}', '\0', '\0']), ('\u{ab85}',
-        ['\u{13b5}', '\0', '\0']), ('\u{ab86}', ['\u{13b6}', '\0', '\0']), ('\u{ab87}', ['\u{13b7}',
-        '\0', '\0']), ('\u{ab88}', ['\u{13b8}', '\0', '\0']), ('\u{ab89}', ['\u{13b9}', '\0',
-        '\0']), ('\u{ab8a}', ['\u{13ba}', '\0', '\0']), ('\u{ab8b}', ['\u{13bb}', '\0', '\0']),
-        ('\u{ab8c}', ['\u{13bc}', '\0', '\0']), ('\u{ab8d}', ['\u{13bd}', '\0', '\0']), ('\u{ab8e}',
-        ['\u{13be}', '\0', '\0']), ('\u{ab8f}', ['\u{13bf}', '\0', '\0']), ('\u{ab90}', ['\u{13c0}',
-        '\0', '\0']), ('\u{ab91}', ['\u{13c1}', '\0', '\0']), ('\u{ab92}', ['\u{13c2}', '\0',
-        '\0']), ('\u{ab93}', ['\u{13c3}', '\0', '\0']), ('\u{ab94}', ['\u{13c4}', '\0', '\0']),
-        ('\u{ab95}', ['\u{13c5}', '\0', '\0']), ('\u{ab96}', ['\u{13c6}', '\0', '\0']), ('\u{ab97}',
-        ['\u{13c7}', '\0', '\0']), ('\u{ab98}', ['\u{13c8}', '\0', '\0']), ('\u{ab99}', ['\u{13c9}',
-        '\0', '\0']), ('\u{ab9a}', ['\u{13ca}', '\0', '\0']), ('\u{ab9b}', ['\u{13cb}', '\0',
-        '\0']), ('\u{ab9c}', ['\u{13cc}', '\0', '\0']), ('\u{ab9d}', ['\u{13cd}', '\0', '\0']),
-        ('\u{ab9e}', ['\u{13ce}', '\0', '\0']), ('\u{ab9f}', ['\u{13cf}', '\0', '\0']), ('\u{aba0}',
-        ['\u{13d0}', '\0', '\0']), ('\u{aba1}', ['\u{13d1}', '\0', '\0']), ('\u{aba2}', ['\u{13d2}',
-        '\0', '\0']), ('\u{aba3}', ['\u{13d3}', '\0', '\0']), ('\u{aba4}', ['\u{13d4}', '\0',
-        '\0']), ('\u{aba5}', ['\u{13d5}', '\0', '\0']), ('\u{aba6}', ['\u{13d6}', '\0', '\0']),
-        ('\u{aba7}', ['\u{13d7}', '\0', '\0']), ('\u{aba8}', ['\u{13d8}', '\0', '\0']), ('\u{aba9}',
-        ['\u{13d9}', '\0', '\0']), ('\u{abaa}', ['\u{13da}', '\0', '\0']), ('\u{abab}', ['\u{13db}',
-        '\0', '\0']), ('\u{abac}', ['\u{13dc}', '\0', '\0']), ('\u{abad}', ['\u{13dd}', '\0',
-        '\0']), ('\u{abae}', ['\u{13de}', '\0', '\0']), ('\u{abaf}', ['\u{13df}', '\0', '\0']),
-        ('\u{abb0}', ['\u{13e0}', '\0', '\0']), ('\u{abb1}', ['\u{13e1}', '\0', '\0']), ('\u{abb2}',
-        ['\u{13e2}', '\0', '\0']), ('\u{abb3}', ['\u{13e3}', '\0', '\0']), ('\u{abb4}', ['\u{13e4}',
-        '\0', '\0']), ('\u{abb5}', ['\u{13e5}', '\0', '\0']), ('\u{abb6}', ['\u{13e6}', '\0',
-        '\0']), ('\u{abb7}', ['\u{13e7}', '\0', '\0']), ('\u{abb8}', ['\u{13e8}', '\0', '\0']),
-        ('\u{abb9}', ['\u{13e9}', '\0', '\0']), ('\u{abba}', ['\u{13ea}', '\0', '\0']), ('\u{abbb}',
-        ['\u{13eb}', '\0', '\0']), ('\u{abbc}', ['\u{13ec}', '\0', '\0']), ('\u{abbd}', ['\u{13ed}',
-        '\0', '\0']), ('\u{abbe}', ['\u{13ee}', '\0', '\0']), ('\u{abbf}', ['\u{13ef}', '\0',
-        '\0']), ('\u{fb00}', ['\u{46}', '\u{46}', '\0']), ('\u{fb01}', ['\u{46}', '\u{49}', '\0']),
-        ('\u{fb02}', ['\u{46}', '\u{4c}', '\0']), ('\u{fb03}', ['\u{46}', '\u{46}', '\u{49}']),
-        ('\u{fb04}', ['\u{46}', '\u{46}', '\u{4c}']), ('\u{fb05}', ['\u{53}', '\u{54}', '\0']),
-        ('\u{fb06}', ['\u{53}', '\u{54}', '\0']), ('\u{fb13}', ['\u{544}', '\u{546}', '\0']),
-        ('\u{fb14}', ['\u{544}', '\u{535}', '\0']), ('\u{fb15}', ['\u{544}', '\u{53b}', '\0']),
-        ('\u{fb16}', ['\u{54e}', '\u{546}', '\0']), ('\u{fb17}', ['\u{544}', '\u{53d}', '\0']),
-        ('\u{ff41}', ['\u{ff21}', '\0', '\0']), ('\u{ff42}', ['\u{ff22}', '\0', '\0']), ('\u{ff43}',
-        ['\u{ff23}', '\0', '\0']), ('\u{ff44}', ['\u{ff24}', '\0', '\0']), ('\u{ff45}', ['\u{ff25}',
-        '\0', '\0']), ('\u{ff46}', ['\u{ff26}', '\0', '\0']), ('\u{ff47}', ['\u{ff27}', '\0',
-        '\0']), ('\u{ff48}', ['\u{ff28}', '\0', '\0']), ('\u{ff49}', ['\u{ff29}', '\0', '\0']),
-        ('\u{ff4a}', ['\u{ff2a}', '\0', '\0']), ('\u{ff4b}', ['\u{ff2b}', '\0', '\0']), ('\u{ff4c}',
-        ['\u{ff2c}', '\0', '\0']), ('\u{ff4d}', ['\u{ff2d}', '\0', '\0']), ('\u{ff4e}', ['\u{ff2e}',
-        '\0', '\0']), ('\u{ff4f}', ['\u{ff2f}', '\0', '\0']), ('\u{ff50}', ['\u{ff30}', '\0',
-        '\0']), ('\u{ff51}', ['\u{ff31}', '\0', '\0']), ('\u{ff52}', ['\u{ff32}', '\0', '\0']),
-        ('\u{ff53}', ['\u{ff33}', '\0', '\0']), ('\u{ff54}', ['\u{ff34}', '\0', '\0']), ('\u{ff55}',
-        ['\u{ff35}', '\0', '\0']), ('\u{ff56}', ['\u{ff36}', '\0', '\0']), ('\u{ff57}', ['\u{ff37}',
-        '\0', '\0']), ('\u{ff58}', ['\u{ff38}', '\0', '\0']), ('\u{ff59}', ['\u{ff39}', '\0',
-        '\0']), ('\u{ff5a}', ['\u{ff3a}', '\0', '\0']), ('\u{10428}', ['\u{10400}', '\0', '\0']),
+        ['\u{535}', '\u{552}', '\0']), ('\u{10d0}', ['\u{1c90}', '\0', '\0']), ('\u{10d1}',
+        ['\u{1c91}', '\0', '\0']), ('\u{10d2}', ['\u{1c92}', '\0', '\0']), ('\u{10d3}', ['\u{1c93}',
+        '\0', '\0']), ('\u{10d4}', ['\u{1c94}', '\0', '\0']), ('\u{10d5}', ['\u{1c95}', '\0',
+        '\0']), ('\u{10d6}', ['\u{1c96}', '\0', '\0']), ('\u{10d7}', ['\u{1c97}', '\0', '\0']),
+        ('\u{10d8}', ['\u{1c98}', '\0', '\0']), ('\u{10d9}', ['\u{1c99}', '\0', '\0']), ('\u{10da}',
+        ['\u{1c9a}', '\0', '\0']), ('\u{10db}', ['\u{1c9b}', '\0', '\0']), ('\u{10dc}', ['\u{1c9c}',
+        '\0', '\0']), ('\u{10dd}', ['\u{1c9d}', '\0', '\0']), ('\u{10de}', ['\u{1c9e}', '\0',
+        '\0']), ('\u{10df}', ['\u{1c9f}', '\0', '\0']), ('\u{10e0}', ['\u{1ca0}', '\0', '\0']),
+        ('\u{10e1}', ['\u{1ca1}', '\0', '\0']), ('\u{10e2}', ['\u{1ca2}', '\0', '\0']), ('\u{10e3}',
+        ['\u{1ca3}', '\0', '\0']), ('\u{10e4}', ['\u{1ca4}', '\0', '\0']), ('\u{10e5}', ['\u{1ca5}',
+        '\0', '\0']), ('\u{10e6}', ['\u{1ca6}', '\0', '\0']), ('\u{10e7}', ['\u{1ca7}', '\0',
+        '\0']), ('\u{10e8}', ['\u{1ca8}', '\0', '\0']), ('\u{10e9}', ['\u{1ca9}', '\0', '\0']),
+        ('\u{10ea}', ['\u{1caa}', '\0', '\0']), ('\u{10eb}', ['\u{1cab}', '\0', '\0']), ('\u{10ec}',
+        ['\u{1cac}', '\0', '\0']), ('\u{10ed}', ['\u{1cad}', '\0', '\0']), ('\u{10ee}', ['\u{1cae}',
+        '\0', '\0']), ('\u{10ef}', ['\u{1caf}', '\0', '\0']), ('\u{10f0}', ['\u{1cb0}', '\0',
+        '\0']), ('\u{10f1}', ['\u{1cb1}', '\0', '\0']), ('\u{10f2}', ['\u{1cb2}', '\0', '\0']),
+        ('\u{10f3}', ['\u{1cb3}', '\0', '\0']), ('\u{10f4}', ['\u{1cb4}', '\0', '\0']), ('\u{10f5}',
+        ['\u{1cb5}', '\0', '\0']), ('\u{10f6}', ['\u{1cb6}', '\0', '\0']), ('\u{10f7}', ['\u{1cb7}',
+        '\0', '\0']), ('\u{10f8}', ['\u{1cb8}', '\0', '\0']), ('\u{10f9}', ['\u{1cb9}', '\0',
+        '\0']), ('\u{10fa}', ['\u{1cba}', '\0', '\0']), ('\u{10fd}', ['\u{1cbd}', '\0', '\0']),
+        ('\u{10fe}', ['\u{1cbe}', '\0', '\0']), ('\u{10ff}', ['\u{1cbf}', '\0', '\0']), ('\u{13f8}',
+        ['\u{13f0}', '\0', '\0']), ('\u{13f9}', ['\u{13f1}', '\0', '\0']), ('\u{13fa}', ['\u{13f2}',
+        '\0', '\0']), ('\u{13fb}', ['\u{13f3}', '\0', '\0']), ('\u{13fc}', ['\u{13f4}', '\0',
+        '\0']), ('\u{13fd}', ['\u{13f5}', '\0', '\0']), ('\u{1c80}', ['\u{412}', '\0', '\0']),
+        ('\u{1c81}', ['\u{414}', '\0', '\0']), ('\u{1c82}', ['\u{41e}', '\0', '\0']), ('\u{1c83}',
+        ['\u{421}', '\0', '\0']), ('\u{1c84}', ['\u{422}', '\0', '\0']), ('\u{1c85}', ['\u{422}',
+        '\0', '\0']), ('\u{1c86}', ['\u{42a}', '\0', '\0']), ('\u{1c87}', ['\u{462}', '\0', '\0']),
+        ('\u{1c88}', ['\u{a64a}', '\0', '\0']), ('\u{1d79}', ['\u{a77d}', '\0', '\0']), ('\u{1d7d}',
+        ['\u{2c63}', '\0', '\0']), ('\u{1e01}', ['\u{1e00}', '\0', '\0']), ('\u{1e03}', ['\u{1e02}',
+        '\0', '\0']), ('\u{1e05}', ['\u{1e04}', '\0', '\0']), ('\u{1e07}', ['\u{1e06}', '\0',
+        '\0']), ('\u{1e09}', ['\u{1e08}', '\0', '\0']), ('\u{1e0b}', ['\u{1e0a}', '\0', '\0']),
+        ('\u{1e0d}', ['\u{1e0c}', '\0', '\0']), ('\u{1e0f}', ['\u{1e0e}', '\0', '\0']), ('\u{1e11}',
+        ['\u{1e10}', '\0', '\0']), ('\u{1e13}', ['\u{1e12}', '\0', '\0']), ('\u{1e15}', ['\u{1e14}',
+        '\0', '\0']), ('\u{1e17}', ['\u{1e16}', '\0', '\0']), ('\u{1e19}', ['\u{1e18}', '\0',
+        '\0']), ('\u{1e1b}', ['\u{1e1a}', '\0', '\0']), ('\u{1e1d}', ['\u{1e1c}', '\0', '\0']),
+        ('\u{1e1f}', ['\u{1e1e}', '\0', '\0']), ('\u{1e21}', ['\u{1e20}', '\0', '\0']), ('\u{1e23}',
+        ['\u{1e22}', '\0', '\0']), ('\u{1e25}', ['\u{1e24}', '\0', '\0']), ('\u{1e27}', ['\u{1e26}',
+        '\0', '\0']), ('\u{1e29}', ['\u{1e28}', '\0', '\0']), ('\u{1e2b}', ['\u{1e2a}', '\0',
+        '\0']), ('\u{1e2d}', ['\u{1e2c}', '\0', '\0']), ('\u{1e2f}', ['\u{1e2e}', '\0', '\0']),
+        ('\u{1e31}', ['\u{1e30}', '\0', '\0']), ('\u{1e33}', ['\u{1e32}', '\0', '\0']), ('\u{1e35}',
+        ['\u{1e34}', '\0', '\0']), ('\u{1e37}', ['\u{1e36}', '\0', '\0']), ('\u{1e39}', ['\u{1e38}',
+        '\0', '\0']), ('\u{1e3b}', ['\u{1e3a}', '\0', '\0']), ('\u{1e3d}', ['\u{1e3c}', '\0',
+        '\0']), ('\u{1e3f}', ['\u{1e3e}', '\0', '\0']), ('\u{1e41}', ['\u{1e40}', '\0', '\0']),
+        ('\u{1e43}', ['\u{1e42}', '\0', '\0']), ('\u{1e45}', ['\u{1e44}', '\0', '\0']), ('\u{1e47}',
+        ['\u{1e46}', '\0', '\0']), ('\u{1e49}', ['\u{1e48}', '\0', '\0']), ('\u{1e4b}', ['\u{1e4a}',
+        '\0', '\0']), ('\u{1e4d}', ['\u{1e4c}', '\0', '\0']), ('\u{1e4f}', ['\u{1e4e}', '\0',
+        '\0']), ('\u{1e51}', ['\u{1e50}', '\0', '\0']), ('\u{1e53}', ['\u{1e52}', '\0', '\0']),
+        ('\u{1e55}', ['\u{1e54}', '\0', '\0']), ('\u{1e57}', ['\u{1e56}', '\0', '\0']), ('\u{1e59}',
+        ['\u{1e58}', '\0', '\0']), ('\u{1e5b}', ['\u{1e5a}', '\0', '\0']), ('\u{1e5d}', ['\u{1e5c}',
+        '\0', '\0']), ('\u{1e5f}', ['\u{1e5e}', '\0', '\0']), ('\u{1e61}', ['\u{1e60}', '\0',
+        '\0']), ('\u{1e63}', ['\u{1e62}', '\0', '\0']), ('\u{1e65}', ['\u{1e64}', '\0', '\0']),
+        ('\u{1e67}', ['\u{1e66}', '\0', '\0']), ('\u{1e69}', ['\u{1e68}', '\0', '\0']), ('\u{1e6b}',
+        ['\u{1e6a}', '\0', '\0']), ('\u{1e6d}', ['\u{1e6c}', '\0', '\0']), ('\u{1e6f}', ['\u{1e6e}',
+        '\0', '\0']), ('\u{1e71}', ['\u{1e70}', '\0', '\0']), ('\u{1e73}', ['\u{1e72}', '\0',
+        '\0']), ('\u{1e75}', ['\u{1e74}', '\0', '\0']), ('\u{1e77}', ['\u{1e76}', '\0', '\0']),
+        ('\u{1e79}', ['\u{1e78}', '\0', '\0']), ('\u{1e7b}', ['\u{1e7a}', '\0', '\0']), ('\u{1e7d}',
+        ['\u{1e7c}', '\0', '\0']), ('\u{1e7f}', ['\u{1e7e}', '\0', '\0']), ('\u{1e81}', ['\u{1e80}',
+        '\0', '\0']), ('\u{1e83}', ['\u{1e82}', '\0', '\0']), ('\u{1e85}', ['\u{1e84}', '\0',
+        '\0']), ('\u{1e87}', ['\u{1e86}', '\0', '\0']), ('\u{1e89}', ['\u{1e88}', '\0', '\0']),
+        ('\u{1e8b}', ['\u{1e8a}', '\0', '\0']), ('\u{1e8d}', ['\u{1e8c}', '\0', '\0']), ('\u{1e8f}',
+        ['\u{1e8e}', '\0', '\0']), ('\u{1e91}', ['\u{1e90}', '\0', '\0']), ('\u{1e93}', ['\u{1e92}',
+        '\0', '\0']), ('\u{1e95}', ['\u{1e94}', '\0', '\0']), ('\u{1e96}', ['\u{48}', '\u{331}',
+        '\0']), ('\u{1e97}', ['\u{54}', '\u{308}', '\0']), ('\u{1e98}', ['\u{57}', '\u{30a}',
+        '\0']), ('\u{1e99}', ['\u{59}', '\u{30a}', '\0']), ('\u{1e9a}', ['\u{41}', '\u{2be}',
+        '\0']), ('\u{1e9b}', ['\u{1e60}', '\0', '\0']), ('\u{1ea1}', ['\u{1ea0}', '\0', '\0']),
+        ('\u{1ea3}', ['\u{1ea2}', '\0', '\0']), ('\u{1ea5}', ['\u{1ea4}', '\0', '\0']), ('\u{1ea7}',
+        ['\u{1ea6}', '\0', '\0']), ('\u{1ea9}', ['\u{1ea8}', '\0', '\0']), ('\u{1eab}', ['\u{1eaa}',
+        '\0', '\0']), ('\u{1ead}', ['\u{1eac}', '\0', '\0']), ('\u{1eaf}', ['\u{1eae}', '\0',
+        '\0']), ('\u{1eb1}', ['\u{1eb0}', '\0', '\0']), ('\u{1eb3}', ['\u{1eb2}', '\0', '\0']),
+        ('\u{1eb5}', ['\u{1eb4}', '\0', '\0']), ('\u{1eb7}', ['\u{1eb6}', '\0', '\0']), ('\u{1eb9}',
+        ['\u{1eb8}', '\0', '\0']), ('\u{1ebb}', ['\u{1eba}', '\0', '\0']), ('\u{1ebd}', ['\u{1ebc}',
+        '\0', '\0']), ('\u{1ebf}', ['\u{1ebe}', '\0', '\0']), ('\u{1ec1}', ['\u{1ec0}', '\0',
+        '\0']), ('\u{1ec3}', ['\u{1ec2}', '\0', '\0']), ('\u{1ec5}', ['\u{1ec4}', '\0', '\0']),
+        ('\u{1ec7}', ['\u{1ec6}', '\0', '\0']), ('\u{1ec9}', ['\u{1ec8}', '\0', '\0']), ('\u{1ecb}',
+        ['\u{1eca}', '\0', '\0']), ('\u{1ecd}', ['\u{1ecc}', '\0', '\0']), ('\u{1ecf}', ['\u{1ece}',
+        '\0', '\0']), ('\u{1ed1}', ['\u{1ed0}', '\0', '\0']), ('\u{1ed3}', ['\u{1ed2}', '\0',
+        '\0']), ('\u{1ed5}', ['\u{1ed4}', '\0', '\0']), ('\u{1ed7}', ['\u{1ed6}', '\0', '\0']),
+        ('\u{1ed9}', ['\u{1ed8}', '\0', '\0']), ('\u{1edb}', ['\u{1eda}', '\0', '\0']), ('\u{1edd}',
+        ['\u{1edc}', '\0', '\0']), ('\u{1edf}', ['\u{1ede}', '\0', '\0']), ('\u{1ee1}', ['\u{1ee0}',
+        '\0', '\0']), ('\u{1ee3}', ['\u{1ee2}', '\0', '\0']), ('\u{1ee5}', ['\u{1ee4}', '\0',
+        '\0']), ('\u{1ee7}', ['\u{1ee6}', '\0', '\0']), ('\u{1ee9}', ['\u{1ee8}', '\0', '\0']),
+        ('\u{1eeb}', ['\u{1eea}', '\0', '\0']), ('\u{1eed}', ['\u{1eec}', '\0', '\0']), ('\u{1eef}',
+        ['\u{1eee}', '\0', '\0']), ('\u{1ef1}', ['\u{1ef0}', '\0', '\0']), ('\u{1ef3}', ['\u{1ef2}',
+        '\0', '\0']), ('\u{1ef5}', ['\u{1ef4}', '\0', '\0']), ('\u{1ef7}', ['\u{1ef6}', '\0',
+        '\0']), ('\u{1ef9}', ['\u{1ef8}', '\0', '\0']), ('\u{1efb}', ['\u{1efa}', '\0', '\0']),
+        ('\u{1efd}', ['\u{1efc}', '\0', '\0']), ('\u{1eff}', ['\u{1efe}', '\0', '\0']), ('\u{1f00}',
+        ['\u{1f08}', '\0', '\0']), ('\u{1f01}', ['\u{1f09}', '\0', '\0']), ('\u{1f02}', ['\u{1f0a}',
+        '\0', '\0']), ('\u{1f03}', ['\u{1f0b}', '\0', '\0']), ('\u{1f04}', ['\u{1f0c}', '\0',
+        '\0']), ('\u{1f05}', ['\u{1f0d}', '\0', '\0']), ('\u{1f06}', ['\u{1f0e}', '\0', '\0']),
+        ('\u{1f07}', ['\u{1f0f}', '\0', '\0']), ('\u{1f10}', ['\u{1f18}', '\0', '\0']), ('\u{1f11}',
+        ['\u{1f19}', '\0', '\0']), ('\u{1f12}', ['\u{1f1a}', '\0', '\0']), ('\u{1f13}', ['\u{1f1b}',
+        '\0', '\0']), ('\u{1f14}', ['\u{1f1c}', '\0', '\0']), ('\u{1f15}', ['\u{1f1d}', '\0',
+        '\0']), ('\u{1f20}', ['\u{1f28}', '\0', '\0']), ('\u{1f21}', ['\u{1f29}', '\0', '\0']),
+        ('\u{1f22}', ['\u{1f2a}', '\0', '\0']), ('\u{1f23}', ['\u{1f2b}', '\0', '\0']), ('\u{1f24}',
+        ['\u{1f2c}', '\0', '\0']), ('\u{1f25}', ['\u{1f2d}', '\0', '\0']), ('\u{1f26}', ['\u{1f2e}',
+        '\0', '\0']), ('\u{1f27}', ['\u{1f2f}', '\0', '\0']), ('\u{1f30}', ['\u{1f38}', '\0',
+        '\0']), ('\u{1f31}', ['\u{1f39}', '\0', '\0']), ('\u{1f32}', ['\u{1f3a}', '\0', '\0']),
+        ('\u{1f33}', ['\u{1f3b}', '\0', '\0']), ('\u{1f34}', ['\u{1f3c}', '\0', '\0']), ('\u{1f35}',
+        ['\u{1f3d}', '\0', '\0']), ('\u{1f36}', ['\u{1f3e}', '\0', '\0']), ('\u{1f37}', ['\u{1f3f}',
+        '\0', '\0']), ('\u{1f40}', ['\u{1f48}', '\0', '\0']), ('\u{1f41}', ['\u{1f49}', '\0',
+        '\0']), ('\u{1f42}', ['\u{1f4a}', '\0', '\0']), ('\u{1f43}', ['\u{1f4b}', '\0', '\0']),
+        ('\u{1f44}', ['\u{1f4c}', '\0', '\0']), ('\u{1f45}', ['\u{1f4d}', '\0', '\0']), ('\u{1f50}',
+        ['\u{3a5}', '\u{313}', '\0']), ('\u{1f51}', ['\u{1f59}', '\0', '\0']), ('\u{1f52}',
+        ['\u{3a5}', '\u{313}', '\u{300}']), ('\u{1f53}', ['\u{1f5b}', '\0', '\0']), ('\u{1f54}',
+        ['\u{3a5}', '\u{313}', '\u{301}']), ('\u{1f55}', ['\u{1f5d}', '\0', '\0']), ('\u{1f56}',
+        ['\u{3a5}', '\u{313}', '\u{342}']), ('\u{1f57}', ['\u{1f5f}', '\0', '\0']), ('\u{1f60}',
+        ['\u{1f68}', '\0', '\0']), ('\u{1f61}', ['\u{1f69}', '\0', '\0']), ('\u{1f62}', ['\u{1f6a}',
+        '\0', '\0']), ('\u{1f63}', ['\u{1f6b}', '\0', '\0']), ('\u{1f64}', ['\u{1f6c}', '\0',
+        '\0']), ('\u{1f65}', ['\u{1f6d}', '\0', '\0']), ('\u{1f66}', ['\u{1f6e}', '\0', '\0']),
+        ('\u{1f67}', ['\u{1f6f}', '\0', '\0']), ('\u{1f70}', ['\u{1fba}', '\0', '\0']), ('\u{1f71}',
+        ['\u{1fbb}', '\0', '\0']), ('\u{1f72}', ['\u{1fc8}', '\0', '\0']), ('\u{1f73}', ['\u{1fc9}',
+        '\0', '\0']), ('\u{1f74}', ['\u{1fca}', '\0', '\0']), ('\u{1f75}', ['\u{1fcb}', '\0',
+        '\0']), ('\u{1f76}', ['\u{1fda}', '\0', '\0']), ('\u{1f77}', ['\u{1fdb}', '\0', '\0']),
+        ('\u{1f78}', ['\u{1ff8}', '\0', '\0']), ('\u{1f79}', ['\u{1ff9}', '\0', '\0']), ('\u{1f7a}',
+        ['\u{1fea}', '\0', '\0']), ('\u{1f7b}', ['\u{1feb}', '\0', '\0']), ('\u{1f7c}', ['\u{1ffa}',
+        '\0', '\0']), ('\u{1f7d}', ['\u{1ffb}', '\0', '\0']), ('\u{1f80}', ['\u{1f08}', '\u{399}',
+        '\0']), ('\u{1f81}', ['\u{1f09}', '\u{399}', '\0']), ('\u{1f82}', ['\u{1f0a}', '\u{399}',
+        '\0']), ('\u{1f83}', ['\u{1f0b}', '\u{399}', '\0']), ('\u{1f84}', ['\u{1f0c}', '\u{399}',
+        '\0']), ('\u{1f85}', ['\u{1f0d}', '\u{399}', '\0']), ('\u{1f86}', ['\u{1f0e}', '\u{399}',
+        '\0']), ('\u{1f87}', ['\u{1f0f}', '\u{399}', '\0']), ('\u{1f88}', ['\u{1f08}', '\u{399}',
+        '\0']), ('\u{1f89}', ['\u{1f09}', '\u{399}', '\0']), ('\u{1f8a}', ['\u{1f0a}', '\u{399}',
+        '\0']), ('\u{1f8b}', ['\u{1f0b}', '\u{399}', '\0']), ('\u{1f8c}', ['\u{1f0c}', '\u{399}',
+        '\0']), ('\u{1f8d}', ['\u{1f0d}', '\u{399}', '\0']), ('\u{1f8e}', ['\u{1f0e}', '\u{399}',
+        '\0']), ('\u{1f8f}', ['\u{1f0f}', '\u{399}', '\0']), ('\u{1f90}', ['\u{1f28}', '\u{399}',
+        '\0']), ('\u{1f91}', ['\u{1f29}', '\u{399}', '\0']), ('\u{1f92}', ['\u{1f2a}', '\u{399}',
+        '\0']), ('\u{1f93}', ['\u{1f2b}', '\u{399}', '\0']), ('\u{1f94}', ['\u{1f2c}', '\u{399}',
+        '\0']), ('\u{1f95}', ['\u{1f2d}', '\u{399}', '\0']), ('\u{1f96}', ['\u{1f2e}', '\u{399}',
+        '\0']), ('\u{1f97}', ['\u{1f2f}', '\u{399}', '\0']), ('\u{1f98}', ['\u{1f28}', '\u{399}',
+        '\0']), ('\u{1f99}', ['\u{1f29}', '\u{399}', '\0']), ('\u{1f9a}', ['\u{1f2a}', '\u{399}',
+        '\0']), ('\u{1f9b}', ['\u{1f2b}', '\u{399}', '\0']), ('\u{1f9c}', ['\u{1f2c}', '\u{399}',
+        '\0']), ('\u{1f9d}', ['\u{1f2d}', '\u{399}', '\0']), ('\u{1f9e}', ['\u{1f2e}', '\u{399}',
+        '\0']), ('\u{1f9f}', ['\u{1f2f}', '\u{399}', '\0']), ('\u{1fa0}', ['\u{1f68}', '\u{399}',
+        '\0']), ('\u{1fa1}', ['\u{1f69}', '\u{399}', '\0']), ('\u{1fa2}', ['\u{1f6a}', '\u{399}',
+        '\0']), ('\u{1fa3}', ['\u{1f6b}', '\u{399}', '\0']), ('\u{1fa4}', ['\u{1f6c}', '\u{399}',
+        '\0']), ('\u{1fa5}', ['\u{1f6d}', '\u{399}', '\0']), ('\u{1fa6}', ['\u{1f6e}', '\u{399}',
+        '\0']), ('\u{1fa7}', ['\u{1f6f}', '\u{399}', '\0']), ('\u{1fa8}', ['\u{1f68}', '\u{399}',
+        '\0']), ('\u{1fa9}', ['\u{1f69}', '\u{399}', '\0']), ('\u{1faa}', ['\u{1f6a}', '\u{399}',
+        '\0']), ('\u{1fab}', ['\u{1f6b}', '\u{399}', '\0']), ('\u{1fac}', ['\u{1f6c}', '\u{399}',
+        '\0']), ('\u{1fad}', ['\u{1f6d}', '\u{399}', '\0']), ('\u{1fae}', ['\u{1f6e}', '\u{399}',
+        '\0']), ('\u{1faf}', ['\u{1f6f}', '\u{399}', '\0']), ('\u{1fb0}', ['\u{1fb8}', '\0', '\0']),
+        ('\u{1fb1}', ['\u{1fb9}', '\0', '\0']), ('\u{1fb2}', ['\u{1fba}', '\u{399}', '\0']),
+        ('\u{1fb3}', ['\u{391}', '\u{399}', '\0']), ('\u{1fb4}', ['\u{386}', '\u{399}', '\0']),
+        ('\u{1fb6}', ['\u{391}', '\u{342}', '\0']), ('\u{1fb7}', ['\u{391}', '\u{342}', '\u{399}']),
+        ('\u{1fbc}', ['\u{391}', '\u{399}', '\0']), ('\u{1fbe}', ['\u{399}', '\0', '\0']),
+        ('\u{1fc2}', ['\u{1fca}', '\u{399}', '\0']), ('\u{1fc3}', ['\u{397}', '\u{399}', '\0']),
+        ('\u{1fc4}', ['\u{389}', '\u{399}', '\0']), ('\u{1fc6}', ['\u{397}', '\u{342}', '\0']),
+        ('\u{1fc7}', ['\u{397}', '\u{342}', '\u{399}']), ('\u{1fcc}', ['\u{397}', '\u{399}', '\0']),
+        ('\u{1fd0}', ['\u{1fd8}', '\0', '\0']), ('\u{1fd1}', ['\u{1fd9}', '\0', '\0']), ('\u{1fd2}',
+        ['\u{399}', '\u{308}', '\u{300}']), ('\u{1fd3}', ['\u{399}', '\u{308}', '\u{301}']),
+        ('\u{1fd6}', ['\u{399}', '\u{342}', '\0']), ('\u{1fd7}', ['\u{399}', '\u{308}', '\u{342}']),
+        ('\u{1fe0}', ['\u{1fe8}', '\0', '\0']), ('\u{1fe1}', ['\u{1fe9}', '\0', '\0']), ('\u{1fe2}',
+        ['\u{3a5}', '\u{308}', '\u{300}']), ('\u{1fe3}', ['\u{3a5}', '\u{308}', '\u{301}']),
+        ('\u{1fe4}', ['\u{3a1}', '\u{313}', '\0']), ('\u{1fe5}', ['\u{1fec}', '\0', '\0']),
+        ('\u{1fe6}', ['\u{3a5}', '\u{342}', '\0']), ('\u{1fe7}', ['\u{3a5}', '\u{308}', '\u{342}']),
+        ('\u{1ff2}', ['\u{1ffa}', '\u{399}', '\0']), ('\u{1ff3}', ['\u{3a9}', '\u{399}', '\0']),
+        ('\u{1ff4}', ['\u{38f}', '\u{399}', '\0']), ('\u{1ff6}', ['\u{3a9}', '\u{342}', '\0']),
+        ('\u{1ff7}', ['\u{3a9}', '\u{342}', '\u{399}']), ('\u{1ffc}', ['\u{3a9}', '\u{399}', '\0']),
+        ('\u{214e}', ['\u{2132}', '\0', '\0']), ('\u{2170}', ['\u{2160}', '\0', '\0']), ('\u{2171}',
+        ['\u{2161}', '\0', '\0']), ('\u{2172}', ['\u{2162}', '\0', '\0']), ('\u{2173}', ['\u{2163}',
+        '\0', '\0']), ('\u{2174}', ['\u{2164}', '\0', '\0']), ('\u{2175}', ['\u{2165}', '\0',
+        '\0']), ('\u{2176}', ['\u{2166}', '\0', '\0']), ('\u{2177}', ['\u{2167}', '\0', '\0']),
+        ('\u{2178}', ['\u{2168}', '\0', '\0']), ('\u{2179}', ['\u{2169}', '\0', '\0']), ('\u{217a}',
+        ['\u{216a}', '\0', '\0']), ('\u{217b}', ['\u{216b}', '\0', '\0']), ('\u{217c}', ['\u{216c}',
+        '\0', '\0']), ('\u{217d}', ['\u{216d}', '\0', '\0']), ('\u{217e}', ['\u{216e}', '\0',
+        '\0']), ('\u{217f}', ['\u{216f}', '\0', '\0']), ('\u{2184}', ['\u{2183}', '\0', '\0']),
+        ('\u{24d0}', ['\u{24b6}', '\0', '\0']), ('\u{24d1}', ['\u{24b7}', '\0', '\0']), ('\u{24d2}',
+        ['\u{24b8}', '\0', '\0']), ('\u{24d3}', ['\u{24b9}', '\0', '\0']), ('\u{24d4}', ['\u{24ba}',
+        '\0', '\0']), ('\u{24d5}', ['\u{24bb}', '\0', '\0']), ('\u{24d6}', ['\u{24bc}', '\0',
+        '\0']), ('\u{24d7}', ['\u{24bd}', '\0', '\0']), ('\u{24d8}', ['\u{24be}', '\0', '\0']),
+        ('\u{24d9}', ['\u{24bf}', '\0', '\0']), ('\u{24da}', ['\u{24c0}', '\0', '\0']), ('\u{24db}',
+        ['\u{24c1}', '\0', '\0']), ('\u{24dc}', ['\u{24c2}', '\0', '\0']), ('\u{24dd}', ['\u{24c3}',
+        '\0', '\0']), ('\u{24de}', ['\u{24c4}', '\0', '\0']), ('\u{24df}', ['\u{24c5}', '\0',
+        '\0']), ('\u{24e0}', ['\u{24c6}', '\0', '\0']), ('\u{24e1}', ['\u{24c7}', '\0', '\0']),
+        ('\u{24e2}', ['\u{24c8}', '\0', '\0']), ('\u{24e3}', ['\u{24c9}', '\0', '\0']), ('\u{24e4}',
+        ['\u{24ca}', '\0', '\0']), ('\u{24e5}', ['\u{24cb}', '\0', '\0']), ('\u{24e6}', ['\u{24cc}',
+        '\0', '\0']), ('\u{24e7}', ['\u{24cd}', '\0', '\0']), ('\u{24e8}', ['\u{24ce}', '\0',
+        '\0']), ('\u{24e9}', ['\u{24cf}', '\0', '\0']), ('\u{2c30}', ['\u{2c00}', '\0', '\0']),
+        ('\u{2c31}', ['\u{2c01}', '\0', '\0']), ('\u{2c32}', ['\u{2c02}', '\0', '\0']), ('\u{2c33}',
+        ['\u{2c03}', '\0', '\0']), ('\u{2c34}', ['\u{2c04}', '\0', '\0']), ('\u{2c35}', ['\u{2c05}',
+        '\0', '\0']), ('\u{2c36}', ['\u{2c06}', '\0', '\0']), ('\u{2c37}', ['\u{2c07}', '\0',
+        '\0']), ('\u{2c38}', ['\u{2c08}', '\0', '\0']), ('\u{2c39}', ['\u{2c09}', '\0', '\0']),
+        ('\u{2c3a}', ['\u{2c0a}', '\0', '\0']), ('\u{2c3b}', ['\u{2c0b}', '\0', '\0']), ('\u{2c3c}',
+        ['\u{2c0c}', '\0', '\0']), ('\u{2c3d}', ['\u{2c0d}', '\0', '\0']), ('\u{2c3e}', ['\u{2c0e}',
+        '\0', '\0']), ('\u{2c3f}', ['\u{2c0f}', '\0', '\0']), ('\u{2c40}', ['\u{2c10}', '\0',
+        '\0']), ('\u{2c41}', ['\u{2c11}', '\0', '\0']), ('\u{2c42}', ['\u{2c12}', '\0', '\0']),
+        ('\u{2c43}', ['\u{2c13}', '\0', '\0']), ('\u{2c44}', ['\u{2c14}', '\0', '\0']), ('\u{2c45}',
+        ['\u{2c15}', '\0', '\0']), ('\u{2c46}', ['\u{2c16}', '\0', '\0']), ('\u{2c47}', ['\u{2c17}',
+        '\0', '\0']), ('\u{2c48}', ['\u{2c18}', '\0', '\0']), ('\u{2c49}', ['\u{2c19}', '\0',
+        '\0']), ('\u{2c4a}', ['\u{2c1a}', '\0', '\0']), ('\u{2c4b}', ['\u{2c1b}', '\0', '\0']),
+        ('\u{2c4c}', ['\u{2c1c}', '\0', '\0']), ('\u{2c4d}', ['\u{2c1d}', '\0', '\0']), ('\u{2c4e}',
+        ['\u{2c1e}', '\0', '\0']), ('\u{2c4f}', ['\u{2c1f}', '\0', '\0']), ('\u{2c50}', ['\u{2c20}',
+        '\0', '\0']), ('\u{2c51}', ['\u{2c21}', '\0', '\0']), ('\u{2c52}', ['\u{2c22}', '\0',
+        '\0']), ('\u{2c53}', ['\u{2c23}', '\0', '\0']), ('\u{2c54}', ['\u{2c24}', '\0', '\0']),
+        ('\u{2c55}', ['\u{2c25}', '\0', '\0']), ('\u{2c56}', ['\u{2c26}', '\0', '\0']), ('\u{2c57}',
+        ['\u{2c27}', '\0', '\0']), ('\u{2c58}', ['\u{2c28}', '\0', '\0']), ('\u{2c59}', ['\u{2c29}',
+        '\0', '\0']), ('\u{2c5a}', ['\u{2c2a}', '\0', '\0']), ('\u{2c5b}', ['\u{2c2b}', '\0',
+        '\0']), ('\u{2c5c}', ['\u{2c2c}', '\0', '\0']), ('\u{2c5d}', ['\u{2c2d}', '\0', '\0']),
+        ('\u{2c5e}', ['\u{2c2e}', '\0', '\0']), ('\u{2c61}', ['\u{2c60}', '\0', '\0']), ('\u{2c65}',
+        ['\u{23a}', '\0', '\0']), ('\u{2c66}', ['\u{23e}', '\0', '\0']), ('\u{2c68}', ['\u{2c67}',
+        '\0', '\0']), ('\u{2c6a}', ['\u{2c69}', '\0', '\0']), ('\u{2c6c}', ['\u{2c6b}', '\0',
+        '\0']), ('\u{2c73}', ['\u{2c72}', '\0', '\0']), ('\u{2c76}', ['\u{2c75}', '\0', '\0']),
+        ('\u{2c81}', ['\u{2c80}', '\0', '\0']), ('\u{2c83}', ['\u{2c82}', '\0', '\0']), ('\u{2c85}',
+        ['\u{2c84}', '\0', '\0']), ('\u{2c87}', ['\u{2c86}', '\0', '\0']), ('\u{2c89}', ['\u{2c88}',
+        '\0', '\0']), ('\u{2c8b}', ['\u{2c8a}', '\0', '\0']), ('\u{2c8d}', ['\u{2c8c}', '\0',
+        '\0']), ('\u{2c8f}', ['\u{2c8e}', '\0', '\0']), ('\u{2c91}', ['\u{2c90}', '\0', '\0']),
+        ('\u{2c93}', ['\u{2c92}', '\0', '\0']), ('\u{2c95}', ['\u{2c94}', '\0', '\0']), ('\u{2c97}',
+        ['\u{2c96}', '\0', '\0']), ('\u{2c99}', ['\u{2c98}', '\0', '\0']), ('\u{2c9b}', ['\u{2c9a}',
+        '\0', '\0']), ('\u{2c9d}', ['\u{2c9c}', '\0', '\0']), ('\u{2c9f}', ['\u{2c9e}', '\0',
+        '\0']), ('\u{2ca1}', ['\u{2ca0}', '\0', '\0']), ('\u{2ca3}', ['\u{2ca2}', '\0', '\0']),
+        ('\u{2ca5}', ['\u{2ca4}', '\0', '\0']), ('\u{2ca7}', ['\u{2ca6}', '\0', '\0']), ('\u{2ca9}',
+        ['\u{2ca8}', '\0', '\0']), ('\u{2cab}', ['\u{2caa}', '\0', '\0']), ('\u{2cad}', ['\u{2cac}',
+        '\0', '\0']), ('\u{2caf}', ['\u{2cae}', '\0', '\0']), ('\u{2cb1}', ['\u{2cb0}', '\0',
+        '\0']), ('\u{2cb3}', ['\u{2cb2}', '\0', '\0']), ('\u{2cb5}', ['\u{2cb4}', '\0', '\0']),
+        ('\u{2cb7}', ['\u{2cb6}', '\0', '\0']), ('\u{2cb9}', ['\u{2cb8}', '\0', '\0']), ('\u{2cbb}',
+        ['\u{2cba}', '\0', '\0']), ('\u{2cbd}', ['\u{2cbc}', '\0', '\0']), ('\u{2cbf}', ['\u{2cbe}',
+        '\0', '\0']), ('\u{2cc1}', ['\u{2cc0}', '\0', '\0']), ('\u{2cc3}', ['\u{2cc2}', '\0',
+        '\0']), ('\u{2cc5}', ['\u{2cc4}', '\0', '\0']), ('\u{2cc7}', ['\u{2cc6}', '\0', '\0']),
+        ('\u{2cc9}', ['\u{2cc8}', '\0', '\0']), ('\u{2ccb}', ['\u{2cca}', '\0', '\0']), ('\u{2ccd}',
+        ['\u{2ccc}', '\0', '\0']), ('\u{2ccf}', ['\u{2cce}', '\0', '\0']), ('\u{2cd1}', ['\u{2cd0}',
+        '\0', '\0']), ('\u{2cd3}', ['\u{2cd2}', '\0', '\0']), ('\u{2cd5}', ['\u{2cd4}', '\0',
+        '\0']), ('\u{2cd7}', ['\u{2cd6}', '\0', '\0']), ('\u{2cd9}', ['\u{2cd8}', '\0', '\0']),
+        ('\u{2cdb}', ['\u{2cda}', '\0', '\0']), ('\u{2cdd}', ['\u{2cdc}', '\0', '\0']), ('\u{2cdf}',
+        ['\u{2cde}', '\0', '\0']), ('\u{2ce1}', ['\u{2ce0}', '\0', '\0']), ('\u{2ce3}', ['\u{2ce2}',
+        '\0', '\0']), ('\u{2cec}', ['\u{2ceb}', '\0', '\0']), ('\u{2cee}', ['\u{2ced}', '\0',
+        '\0']), ('\u{2cf3}', ['\u{2cf2}', '\0', '\0']), ('\u{2d00}', ['\u{10a0}', '\0', '\0']),
+        ('\u{2d01}', ['\u{10a1}', '\0', '\0']), ('\u{2d02}', ['\u{10a2}', '\0', '\0']), ('\u{2d03}',
+        ['\u{10a3}', '\0', '\0']), ('\u{2d04}', ['\u{10a4}', '\0', '\0']), ('\u{2d05}', ['\u{10a5}',
+        '\0', '\0']), ('\u{2d06}', ['\u{10a6}', '\0', '\0']), ('\u{2d07}', ['\u{10a7}', '\0',
+        '\0']), ('\u{2d08}', ['\u{10a8}', '\0', '\0']), ('\u{2d09}', ['\u{10a9}', '\0', '\0']),
+        ('\u{2d0a}', ['\u{10aa}', '\0', '\0']), ('\u{2d0b}', ['\u{10ab}', '\0', '\0']), ('\u{2d0c}',
+        ['\u{10ac}', '\0', '\0']), ('\u{2d0d}', ['\u{10ad}', '\0', '\0']), ('\u{2d0e}', ['\u{10ae}',
+        '\0', '\0']), ('\u{2d0f}', ['\u{10af}', '\0', '\0']), ('\u{2d10}', ['\u{10b0}', '\0',
+        '\0']), ('\u{2d11}', ['\u{10b1}', '\0', '\0']), ('\u{2d12}', ['\u{10b2}', '\0', '\0']),
+        ('\u{2d13}', ['\u{10b3}', '\0', '\0']), ('\u{2d14}', ['\u{10b4}', '\0', '\0']), ('\u{2d15}',
+        ['\u{10b5}', '\0', '\0']), ('\u{2d16}', ['\u{10b6}', '\0', '\0']), ('\u{2d17}', ['\u{10b7}',
+        '\0', '\0']), ('\u{2d18}', ['\u{10b8}', '\0', '\0']), ('\u{2d19}', ['\u{10b9}', '\0',
+        '\0']), ('\u{2d1a}', ['\u{10ba}', '\0', '\0']), ('\u{2d1b}', ['\u{10bb}', '\0', '\0']),
+        ('\u{2d1c}', ['\u{10bc}', '\0', '\0']), ('\u{2d1d}', ['\u{10bd}', '\0', '\0']), ('\u{2d1e}',
+        ['\u{10be}', '\0', '\0']), ('\u{2d1f}', ['\u{10bf}', '\0', '\0']), ('\u{2d20}', ['\u{10c0}',
+        '\0', '\0']), ('\u{2d21}', ['\u{10c1}', '\0', '\0']), ('\u{2d22}', ['\u{10c2}', '\0',
+        '\0']), ('\u{2d23}', ['\u{10c3}', '\0', '\0']), ('\u{2d24}', ['\u{10c4}', '\0', '\0']),
+        ('\u{2d25}', ['\u{10c5}', '\0', '\0']), ('\u{2d27}', ['\u{10c7}', '\0', '\0']), ('\u{2d2d}',
+        ['\u{10cd}', '\0', '\0']), ('\u{a641}', ['\u{a640}', '\0', '\0']), ('\u{a643}', ['\u{a642}',
+        '\0', '\0']), ('\u{a645}', ['\u{a644}', '\0', '\0']), ('\u{a647}', ['\u{a646}', '\0',
+        '\0']), ('\u{a649}', ['\u{a648}', '\0', '\0']), ('\u{a64b}', ['\u{a64a}', '\0', '\0']),
+        ('\u{a64d}', ['\u{a64c}', '\0', '\0']), ('\u{a64f}', ['\u{a64e}', '\0', '\0']), ('\u{a651}',
+        ['\u{a650}', '\0', '\0']), ('\u{a653}', ['\u{a652}', '\0', '\0']), ('\u{a655}', ['\u{a654}',
+        '\0', '\0']), ('\u{a657}', ['\u{a656}', '\0', '\0']), ('\u{a659}', ['\u{a658}', '\0',
+        '\0']), ('\u{a65b}', ['\u{a65a}', '\0', '\0']), ('\u{a65d}', ['\u{a65c}', '\0', '\0']),
+        ('\u{a65f}', ['\u{a65e}', '\0', '\0']), ('\u{a661}', ['\u{a660}', '\0', '\0']), ('\u{a663}',
+        ['\u{a662}', '\0', '\0']), ('\u{a665}', ['\u{a664}', '\0', '\0']), ('\u{a667}', ['\u{a666}',
+        '\0', '\0']), ('\u{a669}', ['\u{a668}', '\0', '\0']), ('\u{a66b}', ['\u{a66a}', '\0',
+        '\0']), ('\u{a66d}', ['\u{a66c}', '\0', '\0']), ('\u{a681}', ['\u{a680}', '\0', '\0']),
+        ('\u{a683}', ['\u{a682}', '\0', '\0']), ('\u{a685}', ['\u{a684}', '\0', '\0']), ('\u{a687}',
+        ['\u{a686}', '\0', '\0']), ('\u{a689}', ['\u{a688}', '\0', '\0']), ('\u{a68b}', ['\u{a68a}',
+        '\0', '\0']), ('\u{a68d}', ['\u{a68c}', '\0', '\0']), ('\u{a68f}', ['\u{a68e}', '\0',
+        '\0']), ('\u{a691}', ['\u{a690}', '\0', '\0']), ('\u{a693}', ['\u{a692}', '\0', '\0']),
+        ('\u{a695}', ['\u{a694}', '\0', '\0']), ('\u{a697}', ['\u{a696}', '\0', '\0']), ('\u{a699}',
+        ['\u{a698}', '\0', '\0']), ('\u{a69b}', ['\u{a69a}', '\0', '\0']), ('\u{a723}', ['\u{a722}',
+        '\0', '\0']), ('\u{a725}', ['\u{a724}', '\0', '\0']), ('\u{a727}', ['\u{a726}', '\0',
+        '\0']), ('\u{a729}', ['\u{a728}', '\0', '\0']), ('\u{a72b}', ['\u{a72a}', '\0', '\0']),
+        ('\u{a72d}', ['\u{a72c}', '\0', '\0']), ('\u{a72f}', ['\u{a72e}', '\0', '\0']), ('\u{a733}',
+        ['\u{a732}', '\0', '\0']), ('\u{a735}', ['\u{a734}', '\0', '\0']), ('\u{a737}', ['\u{a736}',
+        '\0', '\0']), ('\u{a739}', ['\u{a738}', '\0', '\0']), ('\u{a73b}', ['\u{a73a}', '\0',
+        '\0']), ('\u{a73d}', ['\u{a73c}', '\0', '\0']), ('\u{a73f}', ['\u{a73e}', '\0', '\0']),
+        ('\u{a741}', ['\u{a740}', '\0', '\0']), ('\u{a743}', ['\u{a742}', '\0', '\0']), ('\u{a745}',
+        ['\u{a744}', '\0', '\0']), ('\u{a747}', ['\u{a746}', '\0', '\0']), ('\u{a749}', ['\u{a748}',
+        '\0', '\0']), ('\u{a74b}', ['\u{a74a}', '\0', '\0']), ('\u{a74d}', ['\u{a74c}', '\0',
+        '\0']), ('\u{a74f}', ['\u{a74e}', '\0', '\0']), ('\u{a751}', ['\u{a750}', '\0', '\0']),
+        ('\u{a753}', ['\u{a752}', '\0', '\0']), ('\u{a755}', ['\u{a754}', '\0', '\0']), ('\u{a757}',
+        ['\u{a756}', '\0', '\0']), ('\u{a759}', ['\u{a758}', '\0', '\0']), ('\u{a75b}', ['\u{a75a}',
+        '\0', '\0']), ('\u{a75d}', ['\u{a75c}', '\0', '\0']), ('\u{a75f}', ['\u{a75e}', '\0',
+        '\0']), ('\u{a761}', ['\u{a760}', '\0', '\0']), ('\u{a763}', ['\u{a762}', '\0', '\0']),
+        ('\u{a765}', ['\u{a764}', '\0', '\0']), ('\u{a767}', ['\u{a766}', '\0', '\0']), ('\u{a769}',
+        ['\u{a768}', '\0', '\0']), ('\u{a76b}', ['\u{a76a}', '\0', '\0']), ('\u{a76d}', ['\u{a76c}',
+        '\0', '\0']), ('\u{a76f}', ['\u{a76e}', '\0', '\0']), ('\u{a77a}', ['\u{a779}', '\0',
+        '\0']), ('\u{a77c}', ['\u{a77b}', '\0', '\0']), ('\u{a77f}', ['\u{a77e}', '\0', '\0']),
+        ('\u{a781}', ['\u{a780}', '\0', '\0']), ('\u{a783}', ['\u{a782}', '\0', '\0']), ('\u{a785}',
+        ['\u{a784}', '\0', '\0']), ('\u{a787}', ['\u{a786}', '\0', '\0']), ('\u{a78c}', ['\u{a78b}',
+        '\0', '\0']), ('\u{a791}', ['\u{a790}', '\0', '\0']), ('\u{a793}', ['\u{a792}', '\0',
+        '\0']), ('\u{a797}', ['\u{a796}', '\0', '\0']), ('\u{a799}', ['\u{a798}', '\0', '\0']),
+        ('\u{a79b}', ['\u{a79a}', '\0', '\0']), ('\u{a79d}', ['\u{a79c}', '\0', '\0']), ('\u{a79f}',
+        ['\u{a79e}', '\0', '\0']), ('\u{a7a1}', ['\u{a7a0}', '\0', '\0']), ('\u{a7a3}', ['\u{a7a2}',
+        '\0', '\0']), ('\u{a7a5}', ['\u{a7a4}', '\0', '\0']), ('\u{a7a7}', ['\u{a7a6}', '\0',
+        '\0']), ('\u{a7a9}', ['\u{a7a8}', '\0', '\0']), ('\u{a7b5}', ['\u{a7b4}', '\0', '\0']),
+        ('\u{a7b7}', ['\u{a7b6}', '\0', '\0']), ('\u{a7b9}', ['\u{a7b8}', '\0', '\0']), ('\u{ab53}',
+        ['\u{a7b3}', '\0', '\0']), ('\u{ab70}', ['\u{13a0}', '\0', '\0']), ('\u{ab71}', ['\u{13a1}',
+        '\0', '\0']), ('\u{ab72}', ['\u{13a2}', '\0', '\0']), ('\u{ab73}', ['\u{13a3}', '\0',
+        '\0']), ('\u{ab74}', ['\u{13a4}', '\0', '\0']), ('\u{ab75}', ['\u{13a5}', '\0', '\0']),
+        ('\u{ab76}', ['\u{13a6}', '\0', '\0']), ('\u{ab77}', ['\u{13a7}', '\0', '\0']), ('\u{ab78}',
+        ['\u{13a8}', '\0', '\0']), ('\u{ab79}', ['\u{13a9}', '\0', '\0']), ('\u{ab7a}', ['\u{13aa}',
+        '\0', '\0']), ('\u{ab7b}', ['\u{13ab}', '\0', '\0']), ('\u{ab7c}', ['\u{13ac}', '\0',
+        '\0']), ('\u{ab7d}', ['\u{13ad}', '\0', '\0']), ('\u{ab7e}', ['\u{13ae}', '\0', '\0']),
+        ('\u{ab7f}', ['\u{13af}', '\0', '\0']), ('\u{ab80}', ['\u{13b0}', '\0', '\0']), ('\u{ab81}',
+        ['\u{13b1}', '\0', '\0']), ('\u{ab82}', ['\u{13b2}', '\0', '\0']), ('\u{ab83}', ['\u{13b3}',
+        '\0', '\0']), ('\u{ab84}', ['\u{13b4}', '\0', '\0']), ('\u{ab85}', ['\u{13b5}', '\0',
+        '\0']), ('\u{ab86}', ['\u{13b6}', '\0', '\0']), ('\u{ab87}', ['\u{13b7}', '\0', '\0']),
+        ('\u{ab88}', ['\u{13b8}', '\0', '\0']), ('\u{ab89}', ['\u{13b9}', '\0', '\0']), ('\u{ab8a}',
+        ['\u{13ba}', '\0', '\0']), ('\u{ab8b}', ['\u{13bb}', '\0', '\0']), ('\u{ab8c}', ['\u{13bc}',
+        '\0', '\0']), ('\u{ab8d}', ['\u{13bd}', '\0', '\0']), ('\u{ab8e}', ['\u{13be}', '\0',
+        '\0']), ('\u{ab8f}', ['\u{13bf}', '\0', '\0']), ('\u{ab90}', ['\u{13c0}', '\0', '\0']),
+        ('\u{ab91}', ['\u{13c1}', '\0', '\0']), ('\u{ab92}', ['\u{13c2}', '\0', '\0']), ('\u{ab93}',
+        ['\u{13c3}', '\0', '\0']), ('\u{ab94}', ['\u{13c4}', '\0', '\0']), ('\u{ab95}', ['\u{13c5}',
+        '\0', '\0']), ('\u{ab96}', ['\u{13c6}', '\0', '\0']), ('\u{ab97}', ['\u{13c7}', '\0',
+        '\0']), ('\u{ab98}', ['\u{13c8}', '\0', '\0']), ('\u{ab99}', ['\u{13c9}', '\0', '\0']),
+        ('\u{ab9a}', ['\u{13ca}', '\0', '\0']), ('\u{ab9b}', ['\u{13cb}', '\0', '\0']), ('\u{ab9c}',
+        ['\u{13cc}', '\0', '\0']), ('\u{ab9d}', ['\u{13cd}', '\0', '\0']), ('\u{ab9e}', ['\u{13ce}',
+        '\0', '\0']), ('\u{ab9f}', ['\u{13cf}', '\0', '\0']), ('\u{aba0}', ['\u{13d0}', '\0',
+        '\0']), ('\u{aba1}', ['\u{13d1}', '\0', '\0']), ('\u{aba2}', ['\u{13d2}', '\0', '\0']),
+        ('\u{aba3}', ['\u{13d3}', '\0', '\0']), ('\u{aba4}', ['\u{13d4}', '\0', '\0']), ('\u{aba5}',
+        ['\u{13d5}', '\0', '\0']), ('\u{aba6}', ['\u{13d6}', '\0', '\0']), ('\u{aba7}', ['\u{13d7}',
+        '\0', '\0']), ('\u{aba8}', ['\u{13d8}', '\0', '\0']), ('\u{aba9}', ['\u{13d9}', '\0',
+        '\0']), ('\u{abaa}', ['\u{13da}', '\0', '\0']), ('\u{abab}', ['\u{13db}', '\0', '\0']),
+        ('\u{abac}', ['\u{13dc}', '\0', '\0']), ('\u{abad}', ['\u{13dd}', '\0', '\0']), ('\u{abae}',
+        ['\u{13de}', '\0', '\0']), ('\u{abaf}', ['\u{13df}', '\0', '\0']), ('\u{abb0}', ['\u{13e0}',
+        '\0', '\0']), ('\u{abb1}', ['\u{13e1}', '\0', '\0']), ('\u{abb2}', ['\u{13e2}', '\0',
+        '\0']), ('\u{abb3}', ['\u{13e3}', '\0', '\0']), ('\u{abb4}', ['\u{13e4}', '\0', '\0']),
+        ('\u{abb5}', ['\u{13e5}', '\0', '\0']), ('\u{abb6}', ['\u{13e6}', '\0', '\0']), ('\u{abb7}',
+        ['\u{13e7}', '\0', '\0']), ('\u{abb8}', ['\u{13e8}', '\0', '\0']), ('\u{abb9}', ['\u{13e9}',
+        '\0', '\0']), ('\u{abba}', ['\u{13ea}', '\0', '\0']), ('\u{abbb}', ['\u{13eb}', '\0',
+        '\0']), ('\u{abbc}', ['\u{13ec}', '\0', '\0']), ('\u{abbd}', ['\u{13ed}', '\0', '\0']),
+        ('\u{abbe}', ['\u{13ee}', '\0', '\0']), ('\u{abbf}', ['\u{13ef}', '\0', '\0']), ('\u{fb00}',
+        ['\u{46}', '\u{46}', '\0']), ('\u{fb01}', ['\u{46}', '\u{49}', '\0']), ('\u{fb02}',
+        ['\u{46}', '\u{4c}', '\0']), ('\u{fb03}', ['\u{46}', '\u{46}', '\u{49}']), ('\u{fb04}',
+        ['\u{46}', '\u{46}', '\u{4c}']), ('\u{fb05}', ['\u{53}', '\u{54}', '\0']), ('\u{fb06}',
+        ['\u{53}', '\u{54}', '\0']), ('\u{fb13}', ['\u{544}', '\u{546}', '\0']), ('\u{fb14}',
+        ['\u{544}', '\u{535}', '\0']), ('\u{fb15}', ['\u{544}', '\u{53b}', '\0']), ('\u{fb16}',
+        ['\u{54e}', '\u{546}', '\0']), ('\u{fb17}', ['\u{544}', '\u{53d}', '\0']), ('\u{ff41}',
+        ['\u{ff21}', '\0', '\0']), ('\u{ff42}', ['\u{ff22}', '\0', '\0']), ('\u{ff43}', ['\u{ff23}',
+        '\0', '\0']), ('\u{ff44}', ['\u{ff24}', '\0', '\0']), ('\u{ff45}', ['\u{ff25}', '\0',
+        '\0']), ('\u{ff46}', ['\u{ff26}', '\0', '\0']), ('\u{ff47}', ['\u{ff27}', '\0', '\0']),
+        ('\u{ff48}', ['\u{ff28}', '\0', '\0']), ('\u{ff49}', ['\u{ff29}', '\0', '\0']), ('\u{ff4a}',
+        ['\u{ff2a}', '\0', '\0']), ('\u{ff4b}', ['\u{ff2b}', '\0', '\0']), ('\u{ff4c}', ['\u{ff2c}',
+        '\0', '\0']), ('\u{ff4d}', ['\u{ff2d}', '\0', '\0']), ('\u{ff4e}', ['\u{ff2e}', '\0',
+        '\0']), ('\u{ff4f}', ['\u{ff2f}', '\0', '\0']), ('\u{ff50}', ['\u{ff30}', '\0', '\0']),
+        ('\u{ff51}', ['\u{ff31}', '\0', '\0']), ('\u{ff52}', ['\u{ff32}', '\0', '\0']), ('\u{ff53}',
+        ['\u{ff33}', '\0', '\0']), ('\u{ff54}', ['\u{ff34}', '\0', '\0']), ('\u{ff55}', ['\u{ff35}',
+        '\0', '\0']), ('\u{ff56}', ['\u{ff36}', '\0', '\0']), ('\u{ff57}', ['\u{ff37}', '\0',
+        '\0']), ('\u{ff58}', ['\u{ff38}', '\0', '\0']), ('\u{ff59}', ['\u{ff39}', '\0', '\0']),
+        ('\u{ff5a}', ['\u{ff3a}', '\0', '\0']), ('\u{10428}', ['\u{10400}', '\0', '\0']),
         ('\u{10429}', ['\u{10401}', '\0', '\0']), ('\u{1042a}', ['\u{10402}', '\0', '\0']),
         ('\u{1042b}', ['\u{10403}', '\0', '\0']), ('\u{1042c}', ['\u{10404}', '\0', '\0']),
         ('\u{1042d}', ['\u{10405}', '\0', '\0']), ('\u{1042e}', ['\u{10406}', '\0', '\0']),
@@ -2474,6 +2548,22 @@
         ('\u{118da}', ['\u{118ba}', '\0', '\0']), ('\u{118db}', ['\u{118bb}', '\0', '\0']),
         ('\u{118dc}', ['\u{118bc}', '\0', '\0']), ('\u{118dd}', ['\u{118bd}', '\0', '\0']),
         ('\u{118de}', ['\u{118be}', '\0', '\0']), ('\u{118df}', ['\u{118bf}', '\0', '\0']),
+        ('\u{16e60}', ['\u{16e40}', '\0', '\0']), ('\u{16e61}', ['\u{16e41}', '\0', '\0']),
+        ('\u{16e62}', ['\u{16e42}', '\0', '\0']), ('\u{16e63}', ['\u{16e43}', '\0', '\0']),
+        ('\u{16e64}', ['\u{16e44}', '\0', '\0']), ('\u{16e65}', ['\u{16e45}', '\0', '\0']),
+        ('\u{16e66}', ['\u{16e46}', '\0', '\0']), ('\u{16e67}', ['\u{16e47}', '\0', '\0']),
+        ('\u{16e68}', ['\u{16e48}', '\0', '\0']), ('\u{16e69}', ['\u{16e49}', '\0', '\0']),
+        ('\u{16e6a}', ['\u{16e4a}', '\0', '\0']), ('\u{16e6b}', ['\u{16e4b}', '\0', '\0']),
+        ('\u{16e6c}', ['\u{16e4c}', '\0', '\0']), ('\u{16e6d}', ['\u{16e4d}', '\0', '\0']),
+        ('\u{16e6e}', ['\u{16e4e}', '\0', '\0']), ('\u{16e6f}', ['\u{16e4f}', '\0', '\0']),
+        ('\u{16e70}', ['\u{16e50}', '\0', '\0']), ('\u{16e71}', ['\u{16e51}', '\0', '\0']),
+        ('\u{16e72}', ['\u{16e52}', '\0', '\0']), ('\u{16e73}', ['\u{16e53}', '\0', '\0']),
+        ('\u{16e74}', ['\u{16e54}', '\0', '\0']), ('\u{16e75}', ['\u{16e55}', '\0', '\0']),
+        ('\u{16e76}', ['\u{16e56}', '\0', '\0']), ('\u{16e77}', ['\u{16e57}', '\0', '\0']),
+        ('\u{16e78}', ['\u{16e58}', '\0', '\0']), ('\u{16e79}', ['\u{16e59}', '\0', '\0']),
+        ('\u{16e7a}', ['\u{16e5a}', '\0', '\0']), ('\u{16e7b}', ['\u{16e5b}', '\0', '\0']),
+        ('\u{16e7c}', ['\u{16e5c}', '\0', '\0']), ('\u{16e7d}', ['\u{16e5d}', '\0', '\0']),
+        ('\u{16e7e}', ['\u{16e5e}', '\0', '\0']), ('\u{16e7f}', ['\u{16e5f}', '\0', '\0']),
         ('\u{1e922}', ['\u{1e900}', '\0', '\0']), ('\u{1e923}', ['\u{1e901}', '\0', '\0']),
         ('\u{1e924}', ['\u{1e902}', '\0', '\0']), ('\u{1e925}', ['\u{1e903}', '\0', '\0']),
         ('\u{1e926}', ['\u{1e904}', '\0', '\0']), ('\u{1e927}', ['\u{1e905}', '\0', '\0']),
diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs
index 9d037ce..befc1ba 100644
--- a/src/libproc_macro/lib.rs
+++ b/src/libproc_macro/lib.rs
@@ -36,6 +36,8 @@
 #![feature(lang_items)]
 #![feature(optin_builtin_traits)]
 
+#![recursion_limit="256"]
+
 extern crate syntax;
 extern crate syntax_pos;
 extern crate rustc_errors;
diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml
index df68bf1..0ff4dc2 100644
--- a/src/librustc/Cargo.toml
+++ b/src/librustc/Cargo.toml
@@ -15,9 +15,12 @@
 graphviz = { path = "../libgraphviz" }
 jobserver = "0.1"
 lazy_static = "1.0.0"
+scoped-tls = { version = "0.1.1", features = ["nightly"] }
 log = { version = "0.4", features = ["release_max_level_info", "std"] }
-polonius-engine = "0.4.0"
+polonius-engine = "0.5.0"
 proc_macro = { path = "../libproc_macro" }
+rustc-rayon = "0.1.1"
+rustc-rayon-core = "0.1.1"
 rustc_apfloat = { path = "../librustc_apfloat" }
 rustc_target = { path = "../librustc_target" }
 rustc_data_structures = { path = "../librustc_data_structures" }
@@ -26,6 +29,7 @@
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
 backtrace = "0.3.3"
+parking_lot = "0.5.5"
 byteorder = { version = "1.1", features = ["i128"]}
 chalk-engine = { version = "0.6.0", default-features=false }
 
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 9cd9d44..3a152cc 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -500,6 +500,7 @@
     [] TypeOfItem(DefId),
     [] GenericsOfItem(DefId),
     [] PredicatesOfItem(DefId),
+    [] ExplicitPredicatesOfItem(DefId),
     [] InferredOutlivesOf(DefId),
     [] InferredOutlivesCrate(CrateNum),
     [] SuperPredicatesOfItem(DefId),
diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs
index 26470dd..2390d7e 100644
--- a/src/librustc/dep_graph/graph.rs
+++ b/src/librustc/dep_graph/graph.rs
@@ -656,7 +656,7 @@
                     // We failed to mark it green, so we try to force the query.
                     debug!("try_mark_green({:?}) --- trying to force \
                             dependency {:?}", dep_node, dep_dep_node);
-                    if ::ty::maps::force_from_dep_node(tcx, dep_dep_node) {
+                    if ::ty::query::force_from_dep_node(tcx, dep_dep_node) {
                         let dep_dep_node_color = data.colors.borrow().get(dep_dep_node_index);
 
                         match dep_dep_node_color {
@@ -742,14 +742,14 @@
             // and emit other diagnostics before these diagnostics are emitted.
             // Such diagnostics should be emitted after these.
             // See https://github.com/rust-lang/rust/issues/48685
-            let diagnostics = tcx.on_disk_query_result_cache
+            let diagnostics = tcx.queries.on_disk_cache
                                  .load_diagnostics(tcx, prev_dep_node_index);
 
             if diagnostics.len() > 0 {
                 let handle = tcx.sess.diagnostic();
 
                 // Promote the previous diagnostics to the current session.
-                tcx.on_disk_query_result_cache
+                tcx.queries.on_disk_cache
                    .store_diagnostics(dep_node_index, diagnostics.clone());
 
                 for diagnostic in diagnostics {
diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs
index 2662e70..1435957 100644
--- a/src/librustc/diagnostics.rs
+++ b/src/librustc/diagnostics.rs
@@ -637,8 +637,8 @@
 ```compile_fail,E0152
 #![feature(lang_items)]
 
-#[lang = "panic_fmt"]
-struct Foo; // error: duplicate lang item found: `panic_fmt`
+#[lang = "panic_impl"]
+struct Foo; // error: duplicate lang item found: `panic_impl`
 ```
 
 Lang items are already implemented in the standard library. Unless you are
@@ -824,7 +824,7 @@
 #![feature(lang_items)]
 
 extern "C" {
-    #[lang = "panic_fmt"] // ok!
+    #[lang = "panic_impl"] // ok!
     fn cake();
 }
 ```
@@ -1958,8 +1958,6 @@
 Erroneous code example:
 
 ```compile_fail,E0692
-#![feature(repr_transparent)]
-
 #[repr(transparent, C)] // error: incompatible representation hints
 struct Grams(f32);
 ```
@@ -1969,8 +1967,6 @@
 either the `transparent` hint or the other hints, like this:
 
 ```
-#![feature(repr_transparent)]
-
 #[repr(transparent)]
 struct Grams(f32);
 ```
@@ -1978,8 +1974,6 @@
 Alternatively, move the other attributes to the contained type:
 
 ```
-#![feature(repr_transparent)]
-
 #[repr(C)]
 struct Foo {
     x: i32,
@@ -1994,8 +1988,6 @@
 attributes may have unintended side effects on the representation:
 
 ```
-#![feature(repr_transparent)]
-
 #[repr(transparent)]
 struct Grams(f32);
 
@@ -2011,13 +2003,13 @@
 transparent wrapper around a float. This can make a difference for the ABI.
 "##,
 
-E0909: r##"
+E0700: r##"
 The `impl Trait` return type captures lifetime parameters that do not
 appear within the `impl Trait` itself.
 
 Erroneous code example:
 
-```compile-fail,E0909
+```compile-fail,E0700
 use std::cell::Cell;
 
 trait Trait<'a> { }
@@ -2058,13 +2050,13 @@
 ```
 "##,
 
-E0910: r##"
+E0701: r##"
 This error indicates that a `#[non_exhaustive]` attribute was incorrectly placed
 on something other than a struct or enum.
 
 Examples of erroneous code:
 
-```compile_fail,E0910
+```compile_fail,E0701
 # #![feature(non_exhaustive)]
 
 #[non_exhaustive]
@@ -2072,13 +2064,13 @@
 ```
 "##,
 
-E0911: r##"
+E0702: r##"
 This error indicates that a `#[non_exhaustive]` attribute had a value. The
 `#[non_exhaustive]` should be empty.
 
 Examples of erroneous code:
 
-```compile_fail,E0911
+```compile_fail,E0702
 # #![feature(non_exhaustive)]
 
 #[non_exhaustive(anything)]
@@ -2139,6 +2131,5 @@
     E0657, // `impl Trait` can only capture lifetimes bound at the fn level
     E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax
     E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders
-
-    E0906, // closures cannot be static
+    E0697, // closures cannot be static
 }
diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs
index 591cb9d..c71b47f 100644
--- a/src/librustc/hir/check_attr.rs
+++ b/src/librustc/hir/check_attr.rs
@@ -126,7 +126,7 @@
             _ => {
                 struct_span_err!(self.tcx.sess,
                                  attr.span,
-                                 E0910,
+                                 E0701,
                                  "attribute can only be applied to a struct or enum")
                     .span_label(item.span, "not a struct or enum")
                     .emit();
@@ -137,7 +137,7 @@
         if attr.meta_item_list().is_some() || attr.value_str().is_some() {
             struct_span_err!(self.tcx.sess,
                              attr.span,
-                             E0911,
+                             E0702,
                              "attribute should be empty")
                 .span_label(item.span, "not empty")
                 .emit();
diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs
index ae1cf60..7c10292 100644
--- a/src/librustc/hir/def.rs
+++ b/src/librustc/hir/def.rs
@@ -16,6 +16,8 @@
 use hir;
 use ty;
 
+use self::Namespace::*;
+
 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum CtorKind {
     /// Constructor function automatically created by a tuple struct/variant.
@@ -35,6 +37,7 @@
     Enum(DefId),
     Variant(DefId),
     Trait(DefId),
+    Existential(DefId),
     TyAlias(DefId),
     TyForeign(DefId),
     TraitAlias(DefId),
@@ -116,6 +119,72 @@
     }
 }
 
+/// Different kinds of symbols don't influence each other.
+///
+/// Therefore, they have a separate universe (namespace).
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+pub enum Namespace {
+    TypeNS,
+    ValueNS,
+    MacroNS,
+}
+
+/// Just a helper ‒ separate structure for each namespace.
+#[derive(Copy, Clone, Default, Debug)]
+pub struct PerNS<T> {
+    pub value_ns: T,
+    pub type_ns: T,
+    pub macro_ns: T,
+}
+
+impl<T> PerNS<T> {
+    pub fn map<U, F: FnMut(T) -> U>(self, mut f: F) -> PerNS<U> {
+        PerNS {
+            value_ns: f(self.value_ns),
+            type_ns: f(self.type_ns),
+            macro_ns: f(self.macro_ns),
+        }
+    }
+}
+
+impl<T> ::std::ops::Index<Namespace> for PerNS<T> {
+    type Output = T;
+    fn index(&self, ns: Namespace) -> &T {
+        match ns {
+            ValueNS => &self.value_ns,
+            TypeNS => &self.type_ns,
+            MacroNS => &self.macro_ns,
+        }
+    }
+}
+
+impl<T> ::std::ops::IndexMut<Namespace> for PerNS<T> {
+    fn index_mut(&mut self, ns: Namespace) -> &mut T {
+        match ns {
+            ValueNS => &mut self.value_ns,
+            TypeNS => &mut self.type_ns,
+            MacroNS => &mut self.macro_ns,
+        }
+    }
+}
+
+impl<T> PerNS<Option<T>> {
+    /// Returns whether all the items in this collection are `None`.
+    pub fn is_empty(&self) -> bool {
+        self.type_ns.is_none() && self.value_ns.is_none() && self.macro_ns.is_none()
+    }
+
+    /// Returns an iterator over the items which are `Some`.
+    pub fn present_items(self) -> impl Iterator<Item=T> {
+        use std::iter::once;
+
+        once(self.type_ns)
+            .chain(once(self.value_ns))
+            .chain(once(self.macro_ns))
+            .filter_map(|it| it)
+    }
+}
+
 /// Definition mapping
 pub type DefMap = NodeMap<PathResolution>;
 
@@ -123,6 +192,10 @@
 /// within.
 pub type ExportMap = DefIdMap<Vec<Export>>;
 
+/// Map used to track the `use` statements within a scope, matching it with all the items in every
+/// namespace.
+pub type ImportMap = NodeMap<PerNS<Option<PathResolution>>>;
+
 #[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
 pub struct Export {
     /// The name of the target.
@@ -134,9 +207,6 @@
     /// The visibility of the export.
     /// We include non-`pub` exports for hygienic macros that get used from extern crates.
     pub vis: ty::Visibility,
-    /// True if from a `use` or and `extern crate`.
-    /// Used in rustdoc.
-    pub is_import: bool,
 }
 
 impl CtorKind {
@@ -165,6 +235,7 @@
             Def::AssociatedTy(id) | Def::TyParam(id) | Def::Struct(id) | Def::StructCtor(id, ..) |
             Def::Union(id) | Def::Trait(id) | Def::Method(id) | Def::Const(id) |
             Def::AssociatedConst(id) | Def::Macro(id, ..) |
+            Def::Existential(id) |
             Def::GlobalAsm(id) | Def::TyForeign(id) => {
                 id
             }
@@ -191,6 +262,7 @@
             Def::VariantCtor(.., CtorKind::Const) => "unit variant",
             Def::VariantCtor(.., CtorKind::Fictive) => "struct variant",
             Def::Enum(..) => "enum",
+            Def::Existential(..) => "existential type",
             Def::TyAlias(..) => "type alias",
             Def::TraitAlias(..) => "trait alias",
             Def::AssociatedTy(..) => "associated type",
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index 5471568..12ccb32 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -502,6 +502,14 @@
             visitor.visit_ty(typ);
             visitor.visit_generics(type_parameters)
         }
+        ItemExistential(ExistTy {ref generics, ref bounds, impl_trait_fn}) => {
+            visitor.visit_id(item.id);
+            walk_generics(visitor, generics);
+            walk_list!(visitor, visit_ty_param_bound, bounds);
+            if let Some(impl_trait_fn) = impl_trait_fn {
+                visitor.visit_def_mention(Def::Fn(impl_trait_fn))
+            }
+        }
         ItemEnum(ref enum_definition, ref type_parameters) => {
             visitor.visit_generics(type_parameters);
             // visit_enum_def() takes care of visiting the Item's NodeId
@@ -596,10 +604,9 @@
             }
             visitor.visit_lifetime(lifetime);
         }
-        TyImplTraitExistential(ref existty, ref lifetimes) => {
-            let ExistTy { ref generics, ref bounds } = *existty;
-            walk_generics(visitor, generics);
-            walk_list!(visitor, visit_ty_param_bound, bounds);
+        TyImplTraitExistential(item_id, def_id, ref lifetimes) => {
+            visitor.visit_def_mention(Def::Existential(def_id));
+            visitor.visit_nested_item(item_id);
             walk_list!(visitor, visit_lifetime, lifetimes);
         }
         TyTypeof(ref expression) => {
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index f816ba9..dd12edb 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -45,7 +45,7 @@
 use hir::HirVec;
 use hir::map::{DefKey, DefPathData, Definitions};
 use hir::def_id::{DefId, DefIndex, DefIndexAddressSpace, CRATE_DEF_INDEX};
-use hir::def::{Def, PathResolution};
+use hir::def::{Def, PathResolution, PerNS};
 use lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES};
 use middle::cstore::CrateStore;
 use rustc_data_structures::indexed_vec::IndexVec;
@@ -152,6 +152,9 @@
     /// Obtain the resolution for a node id
     fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution>;
 
+    /// Obtain the possible resolutions for the given `use` statement.
+    fn get_import(&mut self, id: NodeId) -> PerNS<Option<PathResolution>>;
+
     /// We must keep the set of definitions up to date as we add nodes that weren't in the AST.
     /// This should only return `None` during testing.
     fn definitions(&mut self) -> &mut Definitions;
@@ -179,7 +182,9 @@
     /// Treat `impl Trait` as shorthand for a new universal existential parameter.
     /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
     /// equivalent to a fresh existential parameter like `abstract type T; fn foo() -> T`.
-    Existential,
+    ///
+    /// We store a DefId here so we can look up necessary information later
+    Existential(DefId),
 
     /// `impl Trait` is not accepted in this position.
     Disallowed,
@@ -235,6 +240,7 @@
     Optional,
 }
 
+#[derive(Debug)]
 struct LoweredNodeId {
     node_id: NodeId,
     hir_id: hir::HirId,
@@ -485,16 +491,16 @@
         }
     }
 
-    fn with_hir_id_owner<F>(&mut self, owner: NodeId, f: F)
+    fn with_hir_id_owner<F, T>(&mut self, owner: NodeId, f: F) -> T
     where
-        F: FnOnce(&mut Self),
+        F: FnOnce(&mut Self) -> T,
     {
         let counter = self.item_local_id_counters
             .insert(owner, HIR_ID_COUNTER_LOCKED)
             .unwrap();
         let def_index = self.resolver.definitions().opt_def_index(owner).unwrap();
         self.current_hir_id_owner.push((def_index, counter));
-        f(self);
+        let ret = f(self);
         let (new_def_index, new_counter) = self.current_hir_id_owner.pop().unwrap();
 
         debug_assert!(def_index == new_def_index);
@@ -504,6 +510,7 @@
             .insert(owner, new_counter)
             .unwrap();
         debug_assert!(prev == HIR_ID_COUNTER_LOCKED);
+        ret
     }
 
     /// This method allocates a new HirId for the given NodeId and stores it in
@@ -527,7 +534,10 @@
 
     fn lower_node_id_with_owner(&mut self, ast_node_id: NodeId, owner: NodeId) -> LoweredNodeId {
         self.lower_node_id_generic(ast_node_id, |this| {
-            let local_id_counter = this.item_local_id_counters.get_mut(&owner).unwrap();
+            let local_id_counter = this
+                .item_local_id_counters
+                .get_mut(&owner)
+                .expect("called lower_node_id_with_owner before allocate_hir_id_counter");
             let local_id = *local_id_counter;
 
             // We want to be sure not to modify the counter in the map while it
@@ -536,7 +546,12 @@
             debug_assert!(local_id != HIR_ID_COUNTER_LOCKED);
 
             *local_id_counter += 1;
-            let def_index = this.resolver.definitions().opt_def_index(owner).unwrap();
+            let def_index = this
+                .resolver
+                .definitions()
+                .opt_def_index(owner)
+                .expect("You forgot to call `create_def_with_parent` or are lowering node ids \
+                         that do not belong to the current owner");
 
             hir::HirId {
                 owner: def_index,
@@ -571,6 +586,15 @@
         })
     }
 
+    fn expect_full_def_from_use(&mut self, id: NodeId) -> impl Iterator<Item=Def> {
+        self.resolver.get_import(id).present_items().map(|pr| {
+            if pr.unresolved_segments() != 0 {
+                bug!("path not fully resolved: {:?}", pr);
+            }
+            pr.base_def()
+        })
+    }
+
     fn diagnostic(&self) -> &errors::Handler {
         self.sess.diagnostic()
     }
@@ -1108,26 +1132,93 @@
             TyKind::ImplTrait(ref bounds) => {
                 let span = t.span;
                 match itctx {
-                    ImplTraitContext::Existential => {
-                        let def_index = self.resolver.definitions().opt_def_index(t.id).unwrap();
-                        let hir_bounds = self.lower_bounds(bounds, itctx);
-                        let (lifetimes, lifetime_defs) =
-                            self.lifetimes_from_impl_trait_bounds(def_index, &hir_bounds);
+                    ImplTraitContext::Existential(fn_def_id) => {
 
-                        hir::TyImplTraitExistential(
-                            hir::ExistTy {
+                        // We need to manually repeat the code of `next_id` because the lowering
+                        // needs to happen while the owner_id is pointing to the item itself,
+                        // because items are their own owners
+                        let exist_ty_node_id = self.sess.next_node_id();
+
+                        // Make sure we know that some funky desugaring has been going on here.
+                        // This is a first: there is code in other places like for loop
+                        // desugaring that explicitly states that we don't want to track that.
+                        // Not tracking it makes lints in rustc and clippy very fragile as
+                        // frequently opened issues show.
+                        let exist_ty_span = self.allow_internal_unstable(
+                            CompilerDesugaringKind::ExistentialReturnType,
+                            t.span,
+                        );
+
+                        // Pull a new definition from the ether
+                        let exist_ty_def_index = self
+                            .resolver
+                            .definitions()
+                            .create_def_with_parent(
+                            fn_def_id.index,
+                            exist_ty_node_id,
+                            DefPathData::ExistentialImplTrait,
+                            DefIndexAddressSpace::High,
+                            Mark::root(),
+                            exist_ty_span,
+                        );
+
+                        // the `t` is just for printing debug messages
+                        self.allocate_hir_id_counter(exist_ty_node_id, t);
+
+                        let hir_bounds = self.with_hir_id_owner(exist_ty_node_id, |lctx| {
+                            lctx.lower_bounds(bounds, itctx)
+                        });
+
+                        let (lifetimes, lifetime_defs) = self.lifetimes_from_impl_trait_bounds(
+                            exist_ty_node_id,
+                            exist_ty_def_index,
+                            &hir_bounds,
+                        );
+
+                        self.with_hir_id_owner(exist_ty_node_id, |lctx| {
+                            let exist_ty_item_kind = hir::ItemExistential(hir::ExistTy {
                                 generics: hir::Generics {
                                     params: lifetime_defs,
                                     where_clause: hir::WhereClause {
-                                        id: self.next_id().node_id,
+                                        id: lctx.next_id().node_id,
                                         predicates: Vec::new().into(),
                                     },
                                     span,
                                 },
                                 bounds: hir_bounds,
-                            },
-                            lifetimes,
-                        )
+                                impl_trait_fn: Some(fn_def_id),
+                            });
+                            let exist_ty_id = lctx.lower_node_id(exist_ty_node_id);
+                            // Generate an `existential type Foo: Trait;` declaration
+                            trace!("creating existential type with id {:#?}", exist_ty_id);
+                            // Set the name to `impl Bound1 + Bound2`
+                            let exist_ty_name = Symbol::intern(&pprust::ty_to_string(t));
+
+                            trace!("exist ty def index: {:#?}", exist_ty_def_index);
+                            let exist_ty_item = hir::Item {
+                                id: exist_ty_id.node_id,
+                                hir_id: exist_ty_id.hir_id,
+                                name: exist_ty_name,
+                                attrs: Default::default(),
+                                node: exist_ty_item_kind,
+                                vis: hir::Visibility::Inherited,
+                                span: exist_ty_span,
+                            };
+
+                            // Insert the item into the global list. This usually happens
+                            // automatically for all AST items. But this existential type item
+                            // does not actually exist in the AST.
+                            lctx.items.insert(exist_ty_id.node_id, exist_ty_item);
+
+                            // `impl Trait` now just becomes `Foo<'a, 'b, ..>`
+                            hir::TyImplTraitExistential(
+                                hir::ItemId {
+                                    id: exist_ty_id.node_id
+                                },
+                                DefId::local(exist_ty_def_index),
+                                lifetimes,
+                            )
+                        })
                     }
                     ImplTraitContext::Universal(def_id) => {
                         let def_node_id = self.next_id().node_id;
@@ -1136,7 +1227,7 @@
                         let def_index = self.resolver.definitions().create_def_with_parent(
                             def_id.index,
                             def_node_id,
-                            DefPathData::ImplTrait,
+                            DefPathData::UniversalImplTrait,
                             DefIndexAddressSpace::High,
                             Mark::root(),
                             span,
@@ -1191,6 +1282,7 @@
 
     fn lifetimes_from_impl_trait_bounds(
         &mut self,
+        exist_ty_id: NodeId,
         parent_index: DefIndex,
         bounds: &hir::TyParamBounds,
     ) -> (HirVec<hir::Lifetime>, HirVec<hir::GenericParam>) {
@@ -1200,6 +1292,7 @@
         struct ImplTraitLifetimeCollector<'r, 'a: 'r> {
             context: &'r mut LoweringContext<'a>,
             parent: DefIndex,
+            exist_ty_id: NodeId,
             collect_elided_lifetimes: bool,
             currently_bound_lifetimes: Vec<hir::LifetimeName>,
             already_defined_lifetimes: HashSet<hir::LifetimeName>,
@@ -1294,7 +1387,11 @@
                         name,
                     });
 
-                    let def_node_id = self.context.next_id().node_id;
+                    // We need to manually create the ids here, because the
+                    // definitions will go into the explicit `existential type`
+                    // declaration and thus need to have their owner set to that item
+                    let def_node_id = self.context.sess.next_node_id();
+                    let _ = self.context.lower_node_id_with_owner(def_node_id, self.exist_ty_id);
                     self.context.resolver.definitions().create_def_with_parent(
                         self.parent,
                         def_node_id,
@@ -1306,7 +1403,7 @@
                     let def_lifetime = hir::Lifetime {
                         id: def_node_id,
                         span: lifetime.span,
-                        name: name,
+                        name,
                     };
                     self.output_lifetime_params
                         .push(hir::GenericParam::Lifetime(hir::LifetimeDef {
@@ -1322,6 +1419,7 @@
         let mut lifetime_collector = ImplTraitLifetimeCollector {
             context: self,
             parent: parent_index,
+            exist_ty_id,
             collect_elided_lifetimes: true,
             currently_bound_lifetimes: Vec::new(),
             already_defined_lifetimes: HashSet::new(),
@@ -1532,13 +1630,13 @@
 
     fn lower_path_extra(
         &mut self,
-        id: NodeId,
+        def: Def,
         p: &Path,
         name: Option<Name>,
         param_mode: ParamMode,
     ) -> hir::Path {
         hir::Path {
-            def: self.expect_full_def(id),
+            def,
             segments: p.segments
                 .iter()
                 .map(|segment| {
@@ -1558,7 +1656,8 @@
     }
 
     fn lower_path(&mut self, id: NodeId, p: &Path, param_mode: ParamMode) -> hir::Path {
-        self.lower_path_extra(id, p, None, param_mode)
+        let def = self.expect_full_def(id);
+        self.lower_path_extra(def, p, None, param_mode)
     }
 
     fn lower_path_segment(
@@ -1759,8 +1858,8 @@
                 .collect(),
             output: match decl.output {
                 FunctionRetTy::Ty(ref ty) => match fn_def_id {
-                    Some(_) if impl_trait_return_allow => {
-                        hir::Return(self.lower_ty(ty, ImplTraitContext::Existential))
+                    Some(def_id) if impl_trait_return_allow => {
+                        hir::Return(self.lower_ty(ty, ImplTraitContext::Existential(def_id)))
                     }
                     _ => hir::Return(self.lower_ty(ty, ImplTraitContext::Disallowed)),
                 },
@@ -2363,7 +2462,7 @@
         let path = &tree.prefix;
 
         match tree.kind {
-            UseTreeKind::Simple(rename) => {
+            UseTreeKind::Simple(rename, id1, id2) => {
                 *name = tree.ident().name;
 
                 // First apply the prefix to the path
@@ -2387,7 +2486,58 @@
                     }
                 }
 
-                let path = P(self.lower_path(id, &path, ParamMode::Explicit));
+                let parent_def_index = self.current_hir_id_owner.last().unwrap().0;
+                let mut defs = self.expect_full_def_from_use(id);
+                // we want to return *something* from this function, so hang onto the first item
+                // for later
+                let mut ret_def = defs.next().unwrap_or(Def::Err);
+
+                for (def, &new_node_id) in defs.zip([id1, id2].iter()) {
+                    let vis = vis.clone();
+                    let name = name.clone();
+                    let span = path.span;
+                    self.resolver.definitions().create_def_with_parent(
+                        parent_def_index,
+                        new_node_id,
+                        DefPathData::Misc,
+                        DefIndexAddressSpace::High,
+                        Mark::root(),
+                        span);
+                    self.allocate_hir_id_counter(new_node_id, &path);
+
+                    self.with_hir_id_owner(new_node_id, |this| {
+                        let new_id = this.lower_node_id(new_node_id);
+                        let path = this.lower_path_extra(def, &path, None, ParamMode::Explicit);
+                        let item = hir::ItemUse(P(path), hir::UseKind::Single);
+                        let vis = match vis {
+                            hir::Visibility::Public => hir::Visibility::Public,
+                            hir::Visibility::Crate(sugar) => hir::Visibility::Crate(sugar),
+                            hir::Visibility::Inherited => hir::Visibility::Inherited,
+                            hir::Visibility::Restricted { ref path, id: _ } => {
+                                hir::Visibility::Restricted {
+                                    path: path.clone(),
+                                    // We are allocating a new NodeId here
+                                    id: this.next_id().node_id,
+                                }
+                            }
+                        };
+
+                        this.items.insert(
+                            new_id.node_id,
+                            hir::Item {
+                                id: new_id.node_id,
+                                hir_id: new_id.hir_id,
+                                name: name,
+                                attrs: attrs.clone(),
+                                node: item,
+                                vis,
+                                span,
+                            },
+                        );
+                    });
+                }
+
+                let path = P(self.lower_path_extra(ret_def, &path, None, ParamMode::Explicit));
                 hir::ItemUse(path, hir::UseKind::Single)
             }
             UseTreeKind::Glob => {
@@ -2433,7 +2583,7 @@
                     self.with_hir_id_owner(new_id, |this| {
                         let vis = match vis {
                             hir::Visibility::Public => hir::Visibility::Public,
-                            hir::Visibility::Crate => hir::Visibility::Crate,
+                            hir::Visibility::Crate(sugar) => hir::Visibility::Crate(sugar),
                             hir::Visibility::Inherited => hir::Visibility::Inherited,
                             hir::Visibility::Restricted { ref path, id: _ } => {
                                 hir::Visibility::Restricted {
@@ -2654,7 +2804,7 @@
         match i.node {
             ItemKind::Use(ref use_tree) => {
                 let mut vec = SmallVector::one(hir::ItemId { id: i.id });
-                self.lower_item_id_use_tree(use_tree, &mut vec);
+                self.lower_item_id_use_tree(use_tree, i.id, &mut vec);
                 return vec;
             }
             ItemKind::MacroDef(..) => return SmallVector::new(),
@@ -2663,14 +2813,25 @@
         SmallVector::one(hir::ItemId { id: i.id })
     }
 
-    fn lower_item_id_use_tree(&self, tree: &UseTree, vec: &mut SmallVector<hir::ItemId>) {
+    fn lower_item_id_use_tree(&mut self,
+                              tree: &UseTree,
+                              base_id: NodeId,
+                              vec: &mut SmallVector<hir::ItemId>)
+    {
         match tree.kind {
             UseTreeKind::Nested(ref nested_vec) => for &(ref nested, id) in nested_vec {
                 vec.push(hir::ItemId { id });
-                self.lower_item_id_use_tree(nested, vec);
+                self.lower_item_id_use_tree(nested, id, vec);
             },
             UseTreeKind::Glob => {}
-            UseTreeKind::Simple(..) => {}
+            UseTreeKind::Simple(_, id1, id2) => {
+                for (_, &id) in self.expect_full_def_from_use(base_id)
+                                    .skip(1)
+                                    .zip([id1, id2].iter())
+                {
+                    vec.push(hir::ItemId { id });
+                }
+            },
         }
     }
 
@@ -3093,7 +3254,7 @@
                             span_err!(
                                 this.sess,
                                 fn_decl_span,
-                                E0906,
+                                E0697,
                                 "closures cannot be static"
                             );
                         }
@@ -3704,7 +3865,7 @@
     ) -> hir::Visibility {
         match v.node {
             VisibilityKind::Public => hir::Public,
-            VisibilityKind::Crate(..) => hir::Visibility::Crate,
+            VisibilityKind::Crate(sugar) => hir::Visibility::Crate(sugar),
             VisibilityKind::Restricted { ref path, id, .. } => hir::Visibility::Restricted {
                 path: P(self.lower_path(id, path, ParamMode::Explicit)),
                 id: if let Some(owner) = explicit_owner {
diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs
index 13df1ce..7835d4e 100644
--- a/src/librustc/hir/map/collector.rs
+++ b/src/librustc/hir/map/collector.rs
@@ -463,7 +463,7 @@
     fn visit_vis(&mut self, visibility: &'hir Visibility) {
         match *visibility {
             Visibility::Public |
-            Visibility::Crate |
+            Visibility::Crate(_) |
             Visibility::Inherited => {}
             Visibility::Restricted { id, .. } => {
                 self.insert(id, NodeVisibility(visibility));
diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs
index 03b6dc1..48d959b 100644
--- a/src/librustc/hir/map/def_collector.rs
+++ b/src/librustc/hir/map/def_collector.rs
@@ -88,7 +88,7 @@
         debug!("visit_item: {:?}", i);
 
         // Pick the def data. This need not be unique, but the more
-        // information we encapsulate into
+        // information we encapsulate into, the better
         let def_data = match i.node {
             ItemKind::Impl(..) => DefPathData::Impl,
             ItemKind::Trait(..) => DefPathData::Trait(i.ident.name.as_interned_str()),
@@ -256,9 +256,6 @@
     fn visit_ty(&mut self, ty: &'a Ty) {
         match ty.node {
             TyKind::Mac(..) => return self.visit_macro_invoc(ty.id),
-            TyKind::ImplTrait(..) => {
-                self.create_def(ty.id, DefPathData::ImplTrait, REGULAR_SPACE, ty.span);
-            }
             _ => {}
         }
         visit::walk_ty(self, ty);
diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs
index 838be07..99023a1 100644
--- a/src/librustc/hir/map/definitions.rs
+++ b/src/librustc/hir/map/definitions.rs
@@ -210,30 +210,9 @@
         } = self.disambiguated_data;
 
         ::std::mem::discriminant(data).hash(&mut hasher);
-        match *data {
-            DefPathData::TypeNs(name) |
-            DefPathData::Trait(name) |
-            DefPathData::AssocTypeInTrait(name) |
-            DefPathData::AssocTypeInImpl(name) |
-            DefPathData::ValueNs(name) |
-            DefPathData::Module(name) |
-            DefPathData::MacroDef(name) |
-            DefPathData::TypeParam(name) |
-            DefPathData::LifetimeDef(name) |
-            DefPathData::EnumVariant(name) |
-            DefPathData::Field(name) |
-            DefPathData::GlobalMetaData(name) => {
-                name.hash(&mut hasher);
-            }
-
-            DefPathData::Impl |
-            DefPathData::CrateRoot |
-            DefPathData::Misc |
-            DefPathData::ClosureExpr |
-            DefPathData::StructCtor |
-            DefPathData::AnonConst |
-            DefPathData::ImplTrait => {}
-        };
+        if let Some(name) = data.get_opt_name() {
+            name.hash(&mut hasher);
+        }
 
         disambiguator.hash(&mut hasher);
 
@@ -390,8 +369,10 @@
     StructCtor,
     /// A constant expression (see {ast,hir}::AnonConst).
     AnonConst,
-    /// An `impl Trait` type node.
-    ImplTrait,
+    /// An `impl Trait` type node in argument position.
+    UniversalImplTrait,
+    /// An `impl Trait` type node in return position.
+    ExistentialImplTrait,
 
     /// GlobalMetaData identifies a piece of crate metadata that is global to
     /// a whole crate (as opposed to just one item). GlobalMetaData components
@@ -655,7 +636,8 @@
             ClosureExpr |
             StructCtor |
             AnonConst |
-            ImplTrait => None
+            ExistentialImplTrait |
+            UniversalImplTrait => None
         }
     }
 
@@ -685,7 +667,8 @@
             ClosureExpr => "{{closure}}",
             StructCtor => "{{constructor}}",
             AnonConst => "{{constant}}",
-            ImplTrait => "{{impl-Trait}}",
+            ExistentialImplTrait => "{{exist-impl-Trait}}",
+            UniversalImplTrait => "{{univ-impl-Trait}}",
         };
 
         Symbol::intern(s).as_interned_str()
diff --git a/src/librustc/hir/map/hir_id_validator.rs b/src/librustc/hir/map/hir_id_validator.rs
index a4c9311..b90bca8 100644
--- a/src/librustc/hir/map/hir_id_validator.rs
+++ b/src/librustc/hir/map/hir_id_validator.rs
@@ -96,7 +96,7 @@
                       .keys()
                       .map(|local_id| local_id.as_usize())
                       .max()
-                      .unwrap();
+                      .expect("owning item has no entry");
 
         if max != self.hir_ids_seen.len() - 1 {
             // Collect the missing ItemLocalIds
@@ -113,6 +113,8 @@
                     local_id: ItemLocalId(local_id as u32),
                 };
 
+                trace!("missing hir id {:#?}", hir_id);
+
                 // We are already in ICE mode here, so doing a linear search
                 // should be fine.
                 let (node_id, _) = self.hir_map
@@ -121,7 +123,7 @@
                                        .iter()
                                        .enumerate()
                                        .find(|&(_, &entry)| hir_id == entry)
-                                       .unwrap();
+                                       .expect("no node_to_hir_id entry");
                 let node_id = NodeId::new(node_id);
                 missing_items.push(format!("[local_id: {}, node:{}]",
                                            local_id,
@@ -146,7 +148,7 @@
     }
 
     fn visit_id(&mut self, node_id: NodeId) {
-        let owner = self.owner_def_index.unwrap();
+        let owner = self.owner_def_index.expect("no owner_def_index");
         let stable_id = self.hir_map.definitions().node_to_hir_id[node_id];
 
         if stable_id == hir::DUMMY_HIR_ID {
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index d6de2f5..9df55e5 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -398,6 +398,7 @@
                     ItemFn(..) => Some(Def::Fn(def_id())),
                     ItemMod(..) => Some(Def::Mod(def_id())),
                     ItemGlobalAsm(..) => Some(Def::GlobalAsm(def_id())),
+                    ItemExistential(..) => Some(Def::Existential(def_id())),
                     ItemTy(..) => Some(Def::TyAlias(def_id())),
                     ItemEnum(..) => Some(Def::Enum(def_id())),
                     ItemStruct(..) => Some(Def::Struct(def_id())),
@@ -767,7 +768,7 @@
 
     /// Retrieve the NodeId for `id`'s parent item, or `id` itself if no
     /// parent item is in this map. The "parent item" is the closest parent node
-    /// in the AST which is recorded by the map and is an item, either an item
+    /// in the HIR which is recorded by the map and is an item, either an item
     /// in a module, trait, or impl.
     pub fn get_parent(&self, id: NodeId) -> NodeId {
         match self.walk_parent_nodes(id, |node| match *node {
@@ -1250,6 +1251,7 @@
                 ItemForeignMod(..) => "foreign mod",
                 ItemGlobalAsm(..) => "global asm",
                 ItemTy(..) => "ty",
+                ItemExistential(..) => "existential",
                 ItemEnum(..) => "enum",
                 ItemStruct(..) => "struct",
                 ItemUnion(..) => "union",
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index ebc5996..833090c 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -35,7 +35,7 @@
 use syntax_pos::{Span, DUMMY_SP};
 use syntax::codemap::{self, Spanned};
 use rustc_target::spec::abi::Abi;
-use syntax::ast::{self, Ident, Name, NodeId, DUMMY_NODE_ID, AsmDialect};
+use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, DUMMY_NODE_ID, AsmDialect};
 use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem};
 use syntax::attr::InlineAttr;
 use syntax::ext::hygiene::SyntaxContext;
@@ -45,7 +45,7 @@
 use syntax::util::ThinVec;
 use syntax::util::parser::ExprPrecedence;
 use ty::AdtKind;
-use ty::maps::Providers;
+use ty::query::Providers;
 
 use rustc_data_structures::indexed_vec;
 use rustc_data_structures::sync::{ParallelIterator, par_iter, Send, Sync, scope};
@@ -1693,6 +1693,7 @@
 pub struct ExistTy {
     pub generics: Generics,
     pub bounds: TyParamBounds,
+    pub impl_trait_fn: Option<DefId>,
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
@@ -1723,15 +1724,15 @@
     /// An existentially quantified (there exists a type satisfying) `impl
     /// Bound1 + Bound2 + Bound3` type where `Bound` is a trait or a lifetime.
     ///
-    /// The `ExistTy` structure emulates an
-    /// `abstract type Foo<'a, 'b>: MyTrait<'a, 'b>;`.
+    /// The `Item` is the generated
+    /// `existential type Foo<'a, 'b>: MyTrait<'a, 'b>;`.
     ///
     /// The `HirVec<Lifetime>` is the list of lifetimes applied as parameters
     /// to the `abstract type`, e.g. the `'c` and `'d` in `-> Foo<'c, 'd>`.
     /// This list is only a list of lifetimes and not type parameters
     /// because all in-scope type parameters are captured by `impl Trait`,
     /// so they are resolved directly through the parent `Generics`.
-    TyImplTraitExistential(ExistTy, HirVec<Lifetime>),
+    TyImplTraitExistential(ItemId, DefId, HirVec<Lifetime>),
     /// Unused for now
     TyTypeof(AnonConst),
     /// TyInfer means the type should be inferred instead of it having been
@@ -1953,7 +1954,7 @@
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum Visibility {
     Public,
-    Crate,
+    Crate(CrateSugar),
     Restricted { path: P<Path>, id: NodeId },
     Inherited,
 }
@@ -1964,7 +1965,7 @@
         match self {
             &Public |
             &Inherited => false,
-            &Crate |
+            &Crate(_) |
             &Restricted { .. } => true,
         }
     }
@@ -2091,6 +2092,8 @@
     ItemGlobalAsm(P<GlobalAsm>),
     /// A type alias, e.g. `type Foo = Bar<u8>`
     ItemTy(P<Ty>, Generics),
+    /// A type alias, e.g. `type Foo = Bar<u8>`
+    ItemExistential(ExistTy),
     /// An enum definition, e.g. `enum Foo<A, B> {C<A>, D<B>}`
     ItemEnum(EnumDef, Generics),
     /// A struct definition, e.g. `struct Foo<A> {x: A}`
@@ -2124,6 +2127,7 @@
             ItemForeignMod(..) => "foreign module",
             ItemGlobalAsm(..) => "global asm",
             ItemTy(..) => "type alias",
+            ItemExistential(..) => "existential type",
             ItemEnum(..) => "enum",
             ItemStruct(..) => "struct",
             ItemUnion(..) => "union",
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index 4bee4f9..1beef3f 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -58,6 +58,9 @@
     fn post(&self, _state: &mut State, _node: AnnNode) -> io::Result<()> {
         Ok(())
     }
+    fn try_fetch_item(&self, _: ast::NodeId) -> Option<&hir::Item> {
+        None
+    }
 }
 
 pub struct NoAnn;
@@ -65,6 +68,9 @@
 pub const NO_ANN: &'static dyn PpAnn = &NoAnn;
 
 impl PpAnn for hir::Crate {
+    fn try_fetch_item(&self, item: ast::NodeId) -> Option<&hir::Item> {
+        Some(self.item(item))
+    }
     fn nested(&self, state: &mut State, nested: Nested) -> io::Result<()> {
         match nested {
             Nested::Item(id) => state.print_item(self.item(id.id)),
@@ -413,8 +419,14 @@
                     self.print_lifetime(lifetime)?;
                 }
             }
-            hir::TyImplTraitExistential(ref existty, ref _lifetimes) => {
-                self.print_bounds("impl", &existty.bounds[..])?;
+            hir::TyImplTraitExistential(hir_id, _def_id, ref _lifetimes) => {
+                match self.ann.try_fetch_item(hir_id.id).map(|it| &it.node) {
+                    None => self.word_space("impl {{Trait}}")?,
+                    Some(&hir::ItemExistential(ref exist_ty)) => {
+                        self.print_bounds("impl", &exist_ty.bounds)?;
+                    },
+                    other => bug!("impl Trait pointed to {:#?}", other),
+                }
             }
             hir::TyArray(ref ty, ref length) => {
                 self.s.word("[")?;
@@ -636,6 +648,31 @@
                 self.s.word(";")?;
                 self.end()?; // end the outer ibox
             }
+            hir::ItemExistential(ref exist) => {
+                self.ibox(indent_unit)?;
+                self.ibox(0)?;
+                self.word_nbsp(&visibility_qualified(&item.vis, "existential type"))?;
+                self.print_name(item.name)?;
+                self.print_generic_params(&exist.generics.params)?;
+                self.end()?; // end the inner ibox
+
+                self.print_where_clause(&exist.generics.where_clause)?;
+                self.s.space()?;
+                self.word_space(":")?;
+                let mut real_bounds = Vec::with_capacity(exist.bounds.len());
+                for b in exist.bounds.iter() {
+                    if let TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = *b {
+                        self.s.space()?;
+                        self.word_space("for ?")?;
+                        self.print_trait_ref(&ptr.trait_ref)?;
+                    } else {
+                        real_bounds.push(b.clone());
+                    }
+                }
+                self.print_bounds(":", &real_bounds[..])?;
+                self.s.word(";")?;
+                self.end()?; // end the outer ibox
+            }
             hir::ItemEnum(ref enum_definition, ref params) => {
                 self.print_enum_def(enum_definition, params, item.name, item.span, &item.vis)?;
             }
@@ -801,15 +838,25 @@
 
     pub fn print_visibility(&mut self, vis: &hir::Visibility) -> io::Result<()> {
         match *vis {
-            hir::Public => self.word_nbsp("pub"),
-            hir::Visibility::Crate => self.word_nbsp("pub(crate)"),
+            hir::Public => self.word_nbsp("pub")?,
+            hir::Visibility::Crate(ast::CrateSugar::JustCrate) => self.word_nbsp("crate")?,
+            hir::Visibility::Crate(ast::CrateSugar::PubCrate) => self.word_nbsp("pub(crate)")?,
             hir::Visibility::Restricted { ref path, .. } => {
                 self.s.word("pub(")?;
-                self.print_path(path, false)?;
-                self.word_nbsp(")")
+                if path.segments.len() == 1 && path.segments[0].name == keywords::Super.name() {
+                    // Special case: `super` can print like `pub(super)`.
+                    self.s.word("super")?;
+                } else {
+                    // Everything else requires `in` at present.
+                    self.word_nbsp("in")?;
+                    self.print_path(path, false)?;
+                }
+                self.word_nbsp(")")?;
             }
-            hir::Inherited => Ok(()),
+            hir::Inherited => ()
         }
+
+        Ok(())
     }
 
     pub fn print_defaultness(&mut self, defaultness: hir::Defaultness) -> io::Result<()> {
diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs
index 9b202f5..ed259b2 100644
--- a/src/librustc/ich/impls_hir.rs
+++ b/src/librustc/ich/impls_hir.rs
@@ -310,6 +310,7 @@
 
 impl_stable_hash_for!(struct hir::ExistTy {
     generics,
+    impl_trait_fn,
     bounds
 });
 
@@ -323,7 +324,7 @@
     TyTup(ts),
     TyPath(qpath),
     TyTraitObject(trait_refs, lifetime),
-    TyImplTraitExistential(existty, lifetimes),
+    TyImplTraitExistential(existty, def_id, lifetimes),
     TyTypeof(body_id),
     TyErr,
     TyInfer
@@ -751,6 +752,11 @@
     Type(t)
 });
 
+impl_stable_hash_for!(enum ::syntax::ast::CrateSugar {
+    JustCrate,
+    PubCrate,
+});
+
 impl<'a> HashStable<StableHashingContext<'a>> for hir::Visibility {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
@@ -758,10 +764,12 @@
         mem::discriminant(self).hash_stable(hcx, hasher);
         match *self {
             hir::Visibility::Public |
-            hir::Visibility::Crate |
             hir::Visibility::Inherited => {
                 // No fields to hash.
             }
+            hir::Visibility::Crate(sugar) => {
+                sugar.hash_stable(hcx, hasher);
+            }
             hir::Visibility::Restricted { ref path, id } => {
                 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
                     id.hash_stable(hcx, hasher);
@@ -882,6 +890,7 @@
     ItemForeignMod(foreign_mod),
     ItemGlobalAsm(global_asm),
     ItemTy(ty, generics),
+    ItemExistential(exist),
     ItemEnum(enum_def, generics),
     ItemStruct(variant_data, generics),
     ItemUnion(variant_data, generics),
@@ -1039,6 +1048,7 @@
     Struct(def_id),
     Union(def_id),
     Enum(def_id),
+    Existential(def_id),
     Variant(def_id),
     Trait(def_id),
     TyAlias(def_id),
@@ -1108,8 +1118,7 @@
     ident,
     def,
     vis,
-    span,
-    is_import
+    span
 });
 
 impl<'a> HashStable<StableHashingContext<'a>>
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index 3a37c1c..7b14831 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -411,6 +411,7 @@
 impl_stable_hash_for!(enum ::syntax_pos::hygiene::CompilerDesugaringKind {
     DotFill,
     QuestionMark,
+    ExistentialReturnType,
     Catch
 });
 
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index 04e5788..5e67065 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -510,6 +510,7 @@
 
 impl_stable_hash_for!(struct ::middle::const_val::FrameInfo {
     span,
+    lint_root,
     location
 });
 
@@ -523,21 +524,11 @@
         mem::discriminant(self).hash_stable(hcx, hasher);
 
         match *self {
-            NonConstPath |
             TypeckError |
+            CouldNotResolve |
             CheckMatchError => {
                 // nothing to do
             }
-            UnimplementedConstVal(s) => {
-                s.hash_stable(hcx, hasher);
-            }
-            IndexOutOfBounds { len, index } => {
-                len.hash_stable(hcx, hasher);
-                index.hash_stable(hcx, hasher);
-            }
-            LayoutError(ref layout_error) => {
-                layout_error.hash_stable(hcx, hasher);
-            }
             Miri(ref err, ref trace) => {
                 err.hash_stable(hcx, hasher);
                 trace.hash_stable(hcx, hasher);
@@ -608,8 +599,8 @@
             RemainderByZero |
             DivisionByZero |
             GeneratorResumedAfterReturn |
-            GeneratorResumedAfterPanic |
-            ReferencedConstant => {}
+            GeneratorResumedAfterPanic => {}
+            ReferencedConstant(ref err) => err.hash_stable(hcx, hasher),
             MachineError(ref err) => err.hash_stable(hcx, hasher),
             FunctionPointerTyMismatch(a, b) => {
                 a.hash_stable(hcx, hasher);
diff --git a/src/librustc/infer/anon_types/mod.rs b/src/librustc/infer/anon_types/mod.rs
index 4cc5e885..f068a54 100644
--- a/src/librustc/infer/anon_types/mod.rs
+++ b/src/librustc/infer/anon_types/mod.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use hir::def_id::DefId;
+use hir;
 use infer::{self, InferCtxt, InferOk, TypeVariableOrigin};
 use infer::outlives::free_region_map::FreeRegionRelations;
 use rustc_data_structures::fx::FxHashMap;
@@ -556,7 +557,7 @@
                         let mut err = struct_span_err!(
                             self.tcx.sess,
                             span,
-                            E0909,
+                            E0700,
                             "hidden type for `impl Trait` captures lifetime that \
                              does not appear in bounds",
                         );
@@ -689,8 +690,16 @@
                     // }
                     // ```
                     if let Some(anon_node_id) = tcx.hir.as_local_node_id(def_id) {
-                        let anon_parent_node_id = tcx.hir.get_parent(anon_node_id);
-                        let anon_parent_def_id = tcx.hir.local_def_id(anon_parent_node_id);
+                        let anon_parent_def_id = match tcx.hir.expect_item(anon_node_id).node {
+                            hir::ItemExistential(hir::ExistTy {
+                                impl_trait_fn: Some(parent),
+                                ..
+                            }) => parent,
+                            _ => {
+                                let anon_parent_node_id = tcx.hir.get_parent(anon_node_id);
+                                tcx.hir.local_def_id(anon_parent_node_id)
+                            },
+                        };
                         if self.parent_def_id == anon_parent_def_id {
                             return self.fold_anon_ty(ty, def_id, substs);
                         }
diff --git a/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs b/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs
index 13c849e..b148a74 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs
@@ -77,7 +77,7 @@
             tcx: self.tcx,
             bound_region: *br,
             found_type: None,
-            current_index: ty::DebruijnIndex::INNERMOST,
+            current_index: ty::INNERMOST,
         };
         nested_visitor.visit_ty(arg);
         nested_visitor.found_type
diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs
index cd73da9..680d445 100644
--- a/src/librustc/infer/higher_ranked/mod.rs
+++ b/src/librustc/infer/higher_ranked/mod.rs
@@ -417,8 +417,7 @@
         {
             for (a_br, a_r) in a_map {
                 if *a_r == r {
-                    return infcx.tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::INNERMOST,
-                                                               *a_br));
+                    return infcx.tcx.mk_region(ty::ReLateBound(ty::INNERMOST, *a_br));
                 }
             }
             span_bug!(
@@ -735,7 +734,7 @@
                     // trait checking, and all of the skolemized regions
                     // appear inside predicates, which always have
                     // binders, so this assert is satisfied.
-                    assert!(current_depth > ty::DebruijnIndex::INNERMOST);
+                    assert!(current_depth > ty::INNERMOST);
 
                     // since leak-check passed, this skolemized region
                     // should only have incoming edges from variables
diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs
index 99d7b4e..296808c 100644
--- a/src/librustc/infer/region_constraints/mod.rs
+++ b/src/librustc/infer/region_constraints/mod.rs
@@ -69,6 +69,10 @@
     /// would wind up with a fresh stream of region variables that
     /// have been equated but appear distinct.
     unification_table: ut::UnificationTable<ut::InPlace<ty::RegionVid>>,
+
+    /// a flag set to true when we perform any unifications; this is used
+    /// to micro-optimize `take_and_reset_data`
+    any_unifications: bool,
 }
 
 pub type VarInfos = IndexVec<RegionVid, RegionVariableInfo>;
@@ -234,6 +238,7 @@
 pub struct RegionSnapshot {
     length: usize,
     region_snapshot: ut::Snapshot<ut::InPlace<ty::RegionVid>>,
+    any_unifications: bool,
 }
 
 /// When working with skolemized regions, we often wish to find all of
@@ -280,6 +285,7 @@
             bound_count: 0,
             undo_log: Vec::new(),
             unification_table: ut::UnificationTable::new(),
+            any_unifications: false,
         }
     }
 
@@ -325,6 +331,7 @@
             bound_count: _,
             undo_log: _,
             unification_table,
+            any_unifications,
         } = self;
 
         // Clear the tables of (lubs, glbs), so that we will create
@@ -338,7 +345,10 @@
         // un-unified" state. Note that when we unify `a` and `b`, we
         // also insert `a <= b` and a `b <= a` edges, so the
         // `RegionConstraintData` contains the relationship here.
-        unification_table.reset_unifications(|vid| unify_key::RegionVidKey { min_vid: vid });
+        if *any_unifications {
+            unification_table.reset_unifications(|vid| unify_key::RegionVidKey { min_vid: vid });
+            *any_unifications = false;
+        }
 
         mem::replace(data, RegionConstraintData::default())
     }
@@ -358,6 +368,7 @@
         RegionSnapshot {
             length,
             region_snapshot: self.unification_table.snapshot(),
+            any_unifications: self.any_unifications,
         }
     }
 
@@ -385,6 +396,7 @@
         let c = self.undo_log.pop().unwrap();
         assert!(c == OpenSnapshot);
         self.unification_table.rollback_to(snapshot.region_snapshot);
+        self.any_unifications = snapshot.any_unifications;
     }
 
     fn rollback_undo_entry(&mut self, undo_entry: UndoLogEntry<'tcx>) {
@@ -623,6 +635,7 @@
 
             if let (ty::ReVar(sub), ty::ReVar(sup)) = (*sub, *sup) {
                 self.unification_table.union(sub, sup);
+                self.any_unifications = true;
             }
         }
     }
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 10e8905..102efe2 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -45,7 +45,6 @@
 #![feature(const_fn)]
 #![feature(core_intrinsics)]
 #![feature(drain_filter)]
-#![feature(entry_or_default)]
 #![feature(from_ref)]
 #![feature(fs_read_write)]
 #![feature(iterator_find_map)]
@@ -67,6 +66,7 @@
 #![feature(unboxed_closures)]
 #![feature(trace_macros)]
 #![feature(trusted_len)]
+#![feature(vec_remove_item)]
 #![feature(catch_expr)]
 #![feature(integer_atomics)]
 #![feature(test)]
@@ -83,13 +83,17 @@
 extern crate getopts;
 extern crate graphviz;
 #[macro_use] extern crate lazy_static;
+#[macro_use] extern crate scoped_tls;
 #[cfg(windows)]
 extern crate libc;
 extern crate polonius_engine;
 extern crate rustc_target;
 #[macro_use] extern crate rustc_data_structures;
 extern crate serialize;
+extern crate parking_lot;
 extern crate rustc_errors as errors;
+extern crate rustc_rayon as rayon;
+extern crate rustc_rayon_core as rayon_core;
 #[macro_use] extern crate log;
 #[macro_use] extern crate syntax;
 extern crate syntax_pos;
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index de583e8..7d4a18c 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -17,6 +17,7 @@
 use errors::{Applicability, DiagnosticBuilder};
 use lint::{LintPass, LateLintPass, LintArray};
 use session::Session;
+use syntax::ast;
 use syntax::codemap::Span;
 
 declare_lint! {
@@ -207,6 +208,12 @@
 }
 
 declare_lint! {
+    pub BAD_REPR,
+    Warn,
+    "detects incorrect use of `repr` attribute"
+}
+
+declare_lint! {
     pub DEPRECATED,
     Warn,
     "detects use of deprecated items"
@@ -285,6 +292,18 @@
     "warns about duplicate associated type bindings in generics"
 }
 
+declare_lint! {
+    pub DUPLICATE_MACRO_EXPORTS,
+    Deny,
+    "detects duplicate macro exports"
+}
+
+declare_lint! {
+    pub INTRA_DOC_LINK_RESOLUTION_FAILURE,
+    Warn,
+    "warn about documentation intra links resolution failure"
+}
+
 /// Does nothing as a lint pass, but registers some `Lint`s
 /// which are used by other parts of the compiler.
 #[derive(Copy, Clone)]
@@ -337,6 +356,8 @@
             ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
             UNSTABLE_NAME_COLLISIONS,
             DUPLICATE_ASSOCIATED_TYPE_BINDINGS,
+            DUPLICATE_MACRO_EXPORTS,
+            INTRA_DOC_LINK_RESOLUTION_FAILURE,
         )
     }
 }
@@ -348,6 +369,7 @@
     Normal,
     BareTraitObject(Span, /* is_global */ bool),
     AbsPathWithModule(Span),
+    DuplicatedMacroExports(ast::Ident, Span, Span),
 }
 
 impl BuiltinLintDiagnostics {
@@ -380,6 +402,10 @@
                 };
                 db.span_suggestion_with_applicability(span, "use `crate`", sugg, app);
             }
+            BuiltinLintDiagnostics::DuplicatedMacroExports(ident, earlier_span, later_span) => {
+                db.span_label(later_span, format!("`{}` already exported", ident));
+                db.span_note(earlier_span, "previous macro export is now shadowed");
+            }
         }
     }
 }
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 381bb16..824930a 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -655,6 +655,9 @@
         f(self);
         self.param_env = old_param_env;
     }
+    pub fn current_lint_root(&self) -> ast::NodeId {
+        self.last_ast_node_with_lint_attrs
+    }
 }
 
 impl<'a, 'tcx> LayoutOf for &'a LateContext<'a, 'tcx> {
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 56b7da4..9338e235 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -47,7 +47,7 @@
 use syntax::visit as ast_visit;
 use syntax_pos::Span;
 use ty::TyCtxt;
-use ty::maps::Providers;
+use ty::query::Providers;
 use util::nodemap::NodeMap;
 
 pub use lint::context::{LateContext, EarlyContext, LintContext, LintStore,
diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs
index d7f1167..2fa77be 100644
--- a/src/librustc/middle/const_val.rs
+++ b/src/librustc/middle/const_val.rs
@@ -9,13 +9,15 @@
 // except according to those terms.
 
 use hir::def_id::DefId;
-use ty::{self, TyCtxt, layout};
+use ty;
 use ty::subst::Substs;
+use ty::query::TyCtxtAt;
 use mir::interpret::ConstValue;
 use errors::DiagnosticBuilder;
 
 use graphviz::IntoCow;
 use syntax_pos::Span;
+use syntax::ast;
 
 use std::borrow::Cow;
 use rustc_data_structures::sync::Lrc;
@@ -28,30 +30,26 @@
     Value(ConstValue<'tcx>),
 }
 
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
 pub struct ConstEvalErr<'tcx> {
     pub span: Span,
     pub kind: Lrc<ErrKind<'tcx>>,
 }
 
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
 pub enum ErrKind<'tcx> {
 
-    NonConstPath,
-    UnimplementedConstVal(&'static str),
-    IndexOutOfBounds { len: u64, index: u64 },
-
-    LayoutError(layout::LayoutError<'tcx>),
-
+    CouldNotResolve,
     TypeckError,
     CheckMatchError,
     Miri(::mir::interpret::EvalError<'tcx>, Vec<FrameInfo>),
 }
 
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
 pub struct FrameInfo {
     pub span: Span,
     pub location: String,
+    pub lint_root: Option<ast::NodeId>,
 }
 
 #[derive(Clone, Debug)]
@@ -83,16 +81,7 @@
         }
 
         match *self.kind {
-            NonConstPath        => simple!("non-constant path in constant expression"),
-            UnimplementedConstVal(what) =>
-                simple!("unimplemented constant expression: {}", what),
-            IndexOutOfBounds { len, index } => {
-                simple!("index out of bounds: the len is {} but the index is {}",
-                        len, index)
-            }
-
-            LayoutError(ref err) => Simple(err.to_string().into_cow()),
-
+            CouldNotResolve => simple!("could not resolve"),
             TypeckError => simple!("type-checking failed"),
             CheckMatchError => simple!("match-checking failed"),
             Miri(ref err, ref trace) => Backtrace(err, trace),
@@ -100,64 +89,90 @@
     }
 
     pub fn struct_error(&self,
-        tcx: TyCtxt<'a, 'gcx, 'tcx>,
-        primary_span: Span,
-        primary_kind: &str)
-        -> DiagnosticBuilder<'gcx>
+        tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
+        message: &str)
+        -> Option<DiagnosticBuilder<'tcx>>
     {
-        let mut diag = struct_error(tcx, self.span, "constant evaluation error");
-        self.note(tcx, primary_span, primary_kind, &mut diag);
-        diag
+        self.struct_generic(tcx, message, None, true)
     }
 
-    pub fn note(&self,
-        _tcx: TyCtxt<'a, 'gcx, 'tcx>,
-        primary_span: Span,
-        primary_kind: &str,
-        diag: &mut DiagnosticBuilder)
-    {
-        match self.description() {
-            ConstEvalErrDescription::Simple(message) => {
-                diag.span_label(self.span, message);
-            }
-            ConstEvalErrDescription::Backtrace(miri, frames) => {
-                diag.span_label(self.span, format!("{}", miri));
-                for frame in frames {
-                    diag.span_label(frame.span, format!("inside call to `{}`", frame.location));
-                }
-            }
-        }
-
-        if !primary_span.contains(self.span) {
-            diag.span_note(primary_span,
-                        &format!("for {} here", primary_kind));
+    pub fn report_as_error(&self,
+        tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
+        message: &str
+    ) {
+        let err = self.struct_generic(tcx, message, None, true);
+        if let Some(mut err) = err {
+            err.emit();
         }
     }
 
-    pub fn report(&self,
-        tcx: TyCtxt<'a, 'gcx, 'tcx>,
-        primary_span: Span,
-        primary_kind: &str)
-    {
-        match *self.kind {
-            ErrKind::TypeckError | ErrKind::CheckMatchError => return,
-            ErrKind::Miri(ref miri, _) => {
+    pub fn report_as_lint(&self,
+        tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
+        message: &str,
+        lint_root: ast::NodeId,
+    ) {
+        let lint = self.struct_generic(
+            tcx,
+            message,
+            Some(lint_root),
+            false,
+        );
+        if let Some(mut lint) = lint {
+            lint.emit();
+        }
+    }
+
+    fn struct_generic(
+        &self,
+        tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
+        message: &str,
+        lint_root: Option<ast::NodeId>,
+        as_err: bool,
+    ) -> Option<DiagnosticBuilder<'tcx>> {
+        let (msg, frames): (_, &[_]) = match *self.kind {
+            ErrKind::TypeckError | ErrKind::CheckMatchError => return None,
+            ErrKind::Miri(ref miri, ref frames) => {
                 match miri.kind {
                     ::mir::interpret::EvalErrorKind::TypeckError |
-                    ::mir::interpret::EvalErrorKind::Layout(_) => return,
-                    _ => {},
+                    ::mir::interpret::EvalErrorKind::Layout(_) => return None,
+                    ::mir::interpret::EvalErrorKind::ReferencedConstant(ref inner) => {
+                        inner.struct_generic(tcx, "referenced constant", lint_root, as_err)?.emit();
+                        (miri.to_string(), frames)
+                    },
+                    _ => (miri.to_string(), frames),
                 }
             }
-            _ => {}
+            _ => (self.description().into_oneline().to_string(), &[]),
+        };
+        trace!("reporting const eval failure at {:?}", self.span);
+        let mut err = if as_err {
+            struct_error(tcx, message)
+        } else {
+            let node_id = frames
+                .iter()
+                .rev()
+                .filter_map(|frame| frame.lint_root)
+                .next()
+                .or(lint_root)
+                .expect("some part of a failing const eval must be local");
+            tcx.struct_span_lint_node(
+                ::rustc::lint::builtin::CONST_ERR,
+                node_id,
+                tcx.span,
+                message,
+            )
+        };
+        err.span_label(self.span, msg);
+        for FrameInfo { span, location, .. } in frames {
+            err.span_label(*span, format!("inside call to `{}`", location));
         }
-        self.struct_error(tcx, primary_span, primary_kind).emit();
+        Some(err)
     }
 }
 
 pub fn struct_error<'a, 'gcx, 'tcx>(
-    tcx: TyCtxt<'a, 'gcx, 'tcx>,
-    span: Span,
+    tcx: TyCtxtAt<'a, 'gcx, 'tcx>,
     msg: &str,
-) -> DiagnosticBuilder<'gcx> {
-    struct_span_err!(tcx.sess, span, E0080, "{}", msg)
+) -> DiagnosticBuilder<'tcx> {
+    struct_span_err!(tcx.sess, tcx.span, E0080, "{}", msg)
 }
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index e3b2078..7ebc0d4 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -284,7 +284,7 @@
 fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt,
                                     id: ast::NodeId,
                                     attrs: &[ast::Attribute]) -> bool {
-    if attr::contains_name(attrs, "lang") {
+    if attr::contains_name(attrs, "lang") || attr::contains_name(attrs, "panic_implementation") {
         return true;
     }
 
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index d70f994..fe67691 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -185,6 +185,8 @@
             if let Some(value) = attribute.value_str() {
                 return Some((value, attribute.span));
             }
+        } else if attribute.check_name("panic_implementation") {
+            return Some((Symbol::intern("panic_impl"), attribute.span))
         }
     }
 
@@ -299,7 +301,8 @@
     // lang item, but do not have it defined.
     PanicFnLangItem,                 "panic",                   panic_fn;
     PanicBoundsCheckFnLangItem,      "panic_bounds_check",      panic_bounds_check_fn;
-    PanicFmtLangItem,                "panic_fmt",               panic_fmt;
+    PanicInfoLangItem,               "panic_info",              panic_info;
+    PanicImplLangItem,               "panic_impl",              panic_impl;
 
     ExchangeMallocFnLangItem,        "exchange_malloc",         exchange_malloc_fn;
     BoxFreeFnLangItem,               "box_free",                box_free_fn;
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index f2120d9..959dda6 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -936,16 +936,32 @@
                            span: Span,
                            expr_ty: Ty<'tcx>)
                            -> cmt_<'tcx> {
+        debug!(
+            "cat_rvalue_node(id={:?}, span={:?}, expr_ty={:?})",
+            id,
+            span,
+            expr_ty,
+        );
         let hir_id = self.tcx.hir.node_to_hir_id(id);
         let promotable = self.rvalue_promotable_map.as_ref().map(|m| m.contains(&hir_id.local_id))
                                                             .unwrap_or(false);
 
+        debug!(
+            "cat_rvalue_node: promotable = {:?}",
+            promotable,
+        );
+
         // Always promote `[T; 0]` (even when e.g. borrowed mutably).
         let promotable = match expr_ty.sty {
             ty::TyArray(_, len) if len.assert_usize(self.tcx) == Some(0) => true,
             _ => promotable,
         };
 
+        debug!(
+            "cat_rvalue_node: promotable = {:?} (2)",
+            promotable,
+        );
+
         // Compute maximum lifetime of this rvalue. This is 'static if
         // we can promote to a constant, otherwise equal to enclosing temp
         // lifetime.
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 249651e..40cf78e 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -21,7 +21,7 @@
 use hir::def_id::{DefId, CrateNum};
 use rustc_data_structures::sync::Lrc;
 use ty::{self, TyCtxt};
-use ty::maps::Providers;
+use ty::query::Providers;
 use middle::privacy;
 use session::config;
 use util::nodemap::{NodeSet, FxHashSet};
@@ -267,6 +267,7 @@
                     // inherently and their children are already in the
                     // worklist, as determined by the privacy pass
                     hir::ItemExternCrate(_) | hir::ItemUse(..) |
+                    hir::ItemExistential(..) |
                     hir::ItemTy(..) | hir::ItemStatic(..) |
                     hir::ItemMod(..) | hir::ItemForeignMod(..) |
                     hir::ItemImpl(..) | hir::ItemTrait(..) | hir::ItemTraitAlias(..) |
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 42a08af..e478f49 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -22,13 +22,12 @@
 
 use std::fmt;
 use std::mem;
-use rustc_data_structures::small_vec::SmallVec;
 use rustc_data_structures::sync::Lrc;
 use syntax::codemap;
 use syntax::ast;
 use syntax_pos::{Span, DUMMY_SP};
 use ty::TyCtxt;
-use ty::maps::Providers;
+use ty::query::Providers;
 
 use hir;
 use hir::def_id::DefId;
@@ -280,6 +279,8 @@
     }
 }
 
+pub type ScopeDepth = u32;
+
 /// The region scope tree encodes information about region relationships.
 #[derive(Default, Debug)]
 pub struct ScopeTree {
@@ -297,7 +298,7 @@
     /// conditional expression or repeating block. (Note that the
     /// enclosing scope id for the block associated with a closure is
     /// the closure itself.)
-    parent_map: FxHashMap<Scope, Scope>,
+    parent_map: FxHashMap<Scope, (Scope, ScopeDepth)>,
 
     /// `var_map` maps from a variable or binding id to the block in
     /// which that variable is declared.
@@ -415,11 +416,12 @@
     /// details.
     root_id: Option<hir::ItemLocalId>,
 
-    /// the scope that contains any new variables declared
-    var_parent: Option<Scope>,
+    /// The scope that contains any new variables declared, plus its depth in
+    /// the scope tree.
+    var_parent: Option<(Scope, ScopeDepth)>,
 
-    /// region parent of expressions etc
-    parent: Option<Scope>,
+    /// Region parent of expressions, etc., plus its depth in the scope tree.
+    parent: Option<(Scope, ScopeDepth)>,
 }
 
 struct RegionResolutionVisitor<'a, 'tcx: 'a> {
@@ -499,7 +501,7 @@
 }
 
 impl<'tcx> ScopeTree {
-    pub fn record_scope_parent(&mut self, child: Scope, parent: Option<Scope>) {
+    pub fn record_scope_parent(&mut self, child: Scope, parent: Option<(Scope, ScopeDepth)>) {
         debug!("{:?}.parent = {:?}", child, parent);
 
         if let Some(p) = parent {
@@ -515,7 +517,7 @@
 
     pub fn each_encl_scope<E>(&self, mut e:E) where E: FnMut(Scope, Scope) {
         for (&child, &parent) in &self.parent_map {
-            e(child, parent)
+            e(child, parent.0)
         }
     }
 
@@ -558,7 +560,7 @@
 
     pub fn opt_encl_scope(&self, id: Scope) -> Option<Scope> {
         //! Returns the narrowest scope that encloses `id`, if any.
-        self.parent_map.get(&id).cloned()
+        self.parent_map.get(&id).cloned().map(|(p, _)| p)
     }
 
     #[allow(dead_code)] // used in cfg
@@ -590,7 +592,7 @@
         // returned.
         let mut id = Scope::Node(expr_id);
 
-        while let Some(&p) = self.parent_map.get(&id) {
+        while let Some(&(p, _)) = self.parent_map.get(&id) {
             match p.data() {
                 ScopeData::Destruction(..) => {
                     debug!("temporary_scope({:?}) = {:?} [enclosing]",
@@ -658,57 +660,61 @@
         }
     }
 
-    /// Finds the nearest common ancestor (if any) of two scopes.  That is, finds the smallest
-    /// scope which is greater than or equal to both `scope_a` and `scope_b`.
-    pub fn nearest_common_ancestor(&self,
-                                   scope_a: Scope,
-                                   scope_b: Scope)
-                                   -> Scope {
+    /// Finds the nearest common ancestor of two scopes.  That is, finds the
+    /// smallest scope which is greater than or equal to both `scope_a` and
+    /// `scope_b`.
+    pub fn nearest_common_ancestor(&self, scope_a: Scope, scope_b: Scope) -> Scope {
         if scope_a == scope_b { return scope_a; }
 
-        // Process the lists in tandem from the innermost scope, recording the
-        // scopes seen so far. The first scope that comes up for a second time
-        // is the nearest common ancestor.
-        //
-        // Note: another way to compute the nearest common ancestor is to get
-        // the full scope chain for both scopes and then compare the chains to
-        // find the first scope in a common tail. But getting a parent scope
-        // requires a hash table lookup, and we often have very long scope
-        // chains (10s or 100s of scopes) that only differ by a few elements at
-        // the start. So this algorithm is faster.
+        let mut a = scope_a;
+        let mut b = scope_b;
 
-        let mut ma = Some(&scope_a);
-        let mut mb = Some(&scope_b);
+        // Get the depth of each scope's parent. If either scope has no parent,
+        // it must be the root, which means we can stop immediately because the
+        // root must be the nearest common ancestor. (In practice, this is
+        // moderately common.)
+        let (parent_a, parent_a_depth) = match self.parent_map.get(&a) {
+            Some(pd) => *pd,
+            None => return a,
+        };
+        let (parent_b, parent_b_depth) = match self.parent_map.get(&b) {
+            Some(pd) => *pd,
+            None => return b,
+        };
 
-        // A HashSet<Scope> is a more obvious choice for these, but SmallVec is
-        // faster because the set size is normally small so linear search is
-        // as good or better than a hash table lookup, plus the size is usually
-        // small enough to avoid a heap allocation.
-        let mut seen_a: SmallVec<[&Scope; 32]> = SmallVec::new();
-        let mut seen_b: SmallVec<[&Scope; 32]> = SmallVec::new();
-
-        loop {
-            if let Some(a) = ma {
-                if seen_b.iter().any(|s| *s == a) {
-                    return *a;
-                }
-                seen_a.push(a);
-                ma = self.parent_map.get(&a);
+        if parent_a_depth > parent_b_depth {
+            // `a` is lower than `b`. Move `a` up until it's at the same depth
+            // as `b`. The first move up is trivial because we already found
+            // `parent_a` above; the loop does the remaining N-1 moves.
+            a = parent_a;
+            for _ in 0..(parent_a_depth - parent_b_depth - 1) {
+                a = self.parent_map.get(&a).unwrap().0;
             }
-
-            if let Some(b) = mb {
-                if seen_a.iter().any(|s| *s == b) {
-                    return *b;
-                }
-                seen_b.push(b);
-                mb = self.parent_map.get(&b);
+        } else if parent_b_depth > parent_a_depth {
+            // `b` is lower than `a`.
+            b = parent_b;
+            for _ in 0..(parent_b_depth - parent_a_depth - 1) {
+                b = self.parent_map.get(&b).unwrap().0;
             }
-
-            if ma.is_none() && mb.is_none() {
-                // No nearest common ancestor found.
-                bug!();
-            }
+        } else {
+            // Both scopes are at the same depth, and we know they're not equal
+            // because that case was tested for at the top of this function. So
+            // we can trivially move them both up one level now.
+            assert!(parent_a_depth != 0);
+            a = parent_a;
+            b = parent_b;
         }
+
+        // Now both scopes are at the same level. We move upwards in lockstep
+        // until they match. In practice, this loop is almost always executed
+        // zero times because `a` is almost always a direct ancestor of `b` or
+        // vice versa.
+        while a != b {
+            a = self.parent_map.get(&a).unwrap().0;
+            b = self.parent_map.get(&b).unwrap().0;
+        };
+
+        a
     }
 
     /// Assuming that the provided region was defined within this `ScopeTree`,
@@ -807,7 +813,7 @@
             //
             // extern fn isalnum(c: c_int) -> c_int
         }
-        Some(parent_scope) =>
+        Some((parent_scope, _)) =>
             visitor.scope_tree.record_var_scope(var_id, parent_scope),
     }
 }
@@ -1019,7 +1025,7 @@
             // Keep traversing up while we can.
             match visitor.scope_tree.parent_map.get(&scope) {
                 // Don't cross from closure bodies to their parent.
-                Some(&superscope) => match superscope.data() {
+                Some(&(superscope, _)) => match superscope.data() {
                     ScopeData::CallSite(_) => break,
                     _ => scope = superscope
                 },
@@ -1036,7 +1042,7 @@
                            init: Option<&'tcx hir::Expr>) {
     debug!("resolve_local(pat={:?}, init={:?})", pat, init);
 
-    let blk_scope = visitor.cx.var_parent;
+    let blk_scope = visitor.cx.var_parent.map(|(p, _)| p);
 
     // As an exception to the normal rules governing temporary
     // lifetimes, initializers in a let have a temporary lifetime
@@ -1261,16 +1267,20 @@
 
 impl<'a, 'tcx> RegionResolutionVisitor<'a, 'tcx> {
     /// Records the current parent (if any) as the parent of `child_scope`.
-    fn record_child_scope(&mut self, child_scope: Scope) {
+    /// Returns the depth of `child_scope`.
+    fn record_child_scope(&mut self, child_scope: Scope) -> ScopeDepth {
         let parent = self.cx.parent;
         self.scope_tree.record_scope_parent(child_scope, parent);
+        // If `child_scope` has no parent, it must be the root node, and so has
+        // a depth of 1. Otherwise, its depth is one more than its parent's.
+        parent.map_or(1, |(_p, d)| d + 1)
     }
 
     /// Records the current parent (if any) as the parent of `child_scope`,
     /// and sets `child_scope` as the new current parent.
     fn enter_scope(&mut self, child_scope: Scope) {
-        self.record_child_scope(child_scope);
-        self.cx.parent = Some(child_scope);
+        let child_depth = self.record_child_scope(child_scope);
+        self.cx.parent = Some((child_scope, child_depth));
     }
 
     fn enter_node_scope_with_dtor(&mut self, id: hir::ItemLocalId) {
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 14c1993..f251a3d 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -98,7 +98,7 @@
     }
 
     fn late(hir_map: &Map, def: &hir::LifetimeDef) -> (hir::LifetimeName, Region) {
-        let depth = ty::DebruijnIndex::INNERMOST;
+        let depth = ty::INNERMOST;
         let def_id = hir_map.local_def_id(def.lifetime.id);
         let origin = LifetimeDefOrigin::from_is_in_band(def.in_band);
         debug!(
@@ -114,7 +114,7 @@
     fn late_anon(index: &Cell<u32>) -> Region {
         let i = index.get();
         index.set(i + 1);
-        let depth = ty::DebruijnIndex::INNERMOST;
+        let depth = ty::INNERMOST;
         Region::LateBoundAnon(depth, i)
     }
 
@@ -349,8 +349,8 @@
 
 const ROOT_SCOPE: ScopeRef<'static> = &Scope::Root;
 
-pub fn provide(providers: &mut ty::maps::Providers) {
-    *providers = ty::maps::Providers {
+pub fn provide(providers: &mut ty::query::Providers) {
+    *providers = ty::query::Providers {
         resolve_lifetimes,
 
         named_region_map: |tcx, id| {
@@ -499,7 +499,13 @@
                 };
                 self.with(scope, |_, this| intravisit::walk_item(this, item));
             }
+            hir::ItemExistential(hir::ExistTy { impl_trait_fn: Some(_), .. }) => {
+                // currently existential type declarations are just generated from impl Trait
+                // items. doing anything on this node is irrelevant, as we currently don't need
+                // it.
+            }
             hir::ItemTy(_, ref generics)
+            | hir::ItemExistential(hir::ExistTy { impl_trait_fn: None, ref generics, .. })
             | hir::ItemEnum(_, ref generics)
             | hir::ItemStruct(_, ref generics)
             | hir::ItemUnion(_, ref generics)
@@ -613,7 +619,7 @@
                 };
                 self.with(scope, |_, this| this.visit_ty(&mt.ty));
             }
-            hir::TyImplTraitExistential(ref exist_ty, ref lifetimes) => {
+            hir::TyImplTraitExistential(item_id, _, ref lifetimes) => {
                 // Resolve the lifetimes that are applied to the existential type.
                 // These are resolved in the current scope.
                 // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
@@ -655,10 +661,13 @@
                 // `abstract type MyAnonTy<'b>: MyTrait<'b>;`
                 //                          ^            ^ this gets resolved in the scope of
                 //                                         the exist_ty generics
-                let hir::ExistTy {
-                    ref generics,
-                    ref bounds,
-                } = *exist_ty;
+                let (generics, bounds) = match self.tcx.hir.expect_item(item_id.id).node {
+                    hir::ItemExistential(hir::ExistTy{ ref generics, ref bounds, .. }) => (
+                        generics,
+                        bounds,
+                    ),
+                    ref i => bug!("impl Trait pointed to non-existential type?? {:#?}", i),
+                };
 
                 // We want to start our early-bound indices at the end of the parent scope,
                 // not including any parent `impl Trait`s.
@@ -1861,7 +1870,7 @@
             .map(|(i, input)| {
                 let mut gather = GatherLifetimes {
                     map: self.map,
-                    outer_index: ty::DebruijnIndex::INNERMOST,
+                    outer_index: ty::INNERMOST,
                     have_bound_regions: false,
                     lifetimes: FxHashSet(),
                 };
diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs
index 42e4d38..3c2ea04 100644
--- a/src/librustc/middle/weak_lang_items.rs
+++ b/src/librustc/middle/weak_lang_items.rs
@@ -148,7 +148,7 @@
 ) }
 
 weak_lang_items! {
-    panic_fmt,          PanicFmtLangItem,           rust_begin_unwind;
+    panic_impl,         PanicImplLangItem,          rust_begin_unwind;
     eh_personality,     EhPersonalityLangItem,      rust_eh_personality;
     eh_unwind_resume,   EhUnwindResumeLangItem,     rust_eh_unwind_resume;
     oom,                OomLangItem,                rust_oom;
diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs
index 45819af..bf5bae6 100644
--- a/src/librustc/mir/interpret/error.rs
+++ b/src/librustc/mir/interpret/error.rs
@@ -1,6 +1,7 @@
 use std::{fmt, env};
 
 use mir;
+use middle::const_val::ConstEvalErr;
 use ty::{FnSig, Ty, layout};
 use ty::layout::{Size, Align};
 
@@ -10,21 +11,50 @@
 
 use backtrace::Backtrace;
 
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, RustcEncodable, RustcDecodable)]
 pub struct EvalError<'tcx> {
     pub kind: EvalErrorKind<'tcx, u64>,
-    pub backtrace: Option<Backtrace>,
 }
 
 impl<'tcx> From<EvalErrorKind<'tcx, u64>> for EvalError<'tcx> {
     fn from(kind: EvalErrorKind<'tcx, u64>) -> Self {
-        let backtrace = match env::var("MIRI_BACKTRACE") {
-            Ok(ref val) if !val.is_empty() => Some(Backtrace::new_unresolved()),
-            _ => None
-        };
+        match env::var("MIRI_BACKTRACE") {
+            Ok(ref val) if !val.is_empty() => {
+                let backtrace = Backtrace::new();
+
+                use std::fmt::Write;
+                let mut trace_text = "\n\nAn error occurred in miri:\n".to_string();
+                write!(trace_text, "backtrace frames: {}\n", backtrace.frames().len()).unwrap();
+                'frames: for (i, frame) in backtrace.frames().iter().enumerate() {
+                    if frame.symbols().is_empty() {
+                        write!(trace_text, "{}: no symbols\n", i).unwrap();
+                    }
+                    for symbol in frame.symbols() {
+                        write!(trace_text, "{}: ", i).unwrap();
+                        if let Some(name) = symbol.name() {
+                            write!(trace_text, "{}\n", name).unwrap();
+                        } else {
+                            write!(trace_text, "<unknown>\n").unwrap();
+                        }
+                        write!(trace_text, "\tat ").unwrap();
+                        if let Some(file_path) = symbol.filename() {
+                            write!(trace_text, "{}", file_path.display()).unwrap();
+                        } else {
+                            write!(trace_text, "<unknown_file>").unwrap();
+                        }
+                        if let Some(line) = symbol.lineno() {
+                            write!(trace_text, ":{}\n", line).unwrap();
+                        } else {
+                            write!(trace_text, "\n").unwrap();
+                        }
+                    }
+                }
+                error!("{}", trace_text);
+            },
+            _ => {},
+        }
         EvalError {
             kind,
-            backtrace,
         }
     }
 }
@@ -122,7 +152,7 @@
     TypeckError,
     /// Cannot compute this constant because it depends on another one
     /// which already produced an error
-    ReferencedConstant,
+    ReferencedConstant(ConstEvalErr<'tcx>),
     GeneratorResumedAfterReturn,
     GeneratorResumedAfterPanic,
 }
@@ -238,7 +268,7 @@
                 "there were unresolved type arguments during trait selection",
             TypeckError =>
                 "encountered constants with type errors, stopping evaluation",
-            ReferencedConstant =>
+            ReferencedConstant(_) =>
                 "referenced constant has errors",
             Overflow(mir::BinOp::Add) => "attempt to add with overflow",
             Overflow(mir::BinOp::Sub) => "attempt to subtract with overflow",
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index cc8e8c7..f831b00 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -494,6 +494,13 @@
             Input::Str { .. } => "rust_out".to_string(),
         }
     }
+
+    pub fn get_input(&mut self) -> Option<&mut String> {
+        match *self {
+            Input::File(_) => None,
+            Input::Str { ref mut input, .. } => Some(input),
+        }
+    }
 }
 
 #[derive(Clone)]
@@ -1304,8 +1311,6 @@
         "enable polonius-based borrow-checker"),
     codegen_time_graph: bool = (false, parse_bool, [UNTRACKED],
         "generate a graphical HTML report of time spent in codegen and LLVM"),
-    trans_time_graph: bool = (false, parse_bool, [UNTRACKED],
-        "generate a graphical HTML report of time spent in trans and LLVM"),
     thinlto: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "enable ThinLTO when possible"),
     inline_in_all_cgus: Option<bool> = (None, parse_opt_bool, [TRACKED],
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 8df66d8..076d56f 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -845,10 +845,10 @@
     /// We want to know if we're allowed to do an optimization for crate foo from -z fuel=foo=n.
     /// This expends fuel if applicable, and records fuel if applicable.
     pub fn consider_optimizing<T: Fn() -> String>(&self, crate_name: &str, msg: T) -> bool {
-        assert!(self.query_threads() == 1);
         let mut ret = true;
         match self.optimization_fuel_crate {
             Some(ref c) if c == crate_name => {
+                assert!(self.query_threads() == 1);
                 let fuel = self.optimization_fuel_limit.get();
                 ret = fuel != 0;
                 if fuel == 0 && !self.out_of_fuel.get() {
@@ -862,6 +862,7 @@
         }
         match self.print_fuel_crate {
             Some(ref c) if c == crate_name => {
+                assert!(self.query_threads() == 1);
                 self.print_fuel.set(self.print_fuel.get() + 1);
             }
             _ => {}
diff --git a/src/librustc/traits/engine.rs b/src/librustc/traits/engine.rs
index 8eee6f3..40d5488 100644
--- a/src/librustc/traits/engine.rs
+++ b/src/librustc/traits/engine.rs
@@ -13,7 +13,7 @@
 use hir::def_id::DefId;
 
 use super::{FulfillmentContext, FulfillmentError};
-use super::{ObligationCause, PendingPredicateObligation, PredicateObligation};
+use super::{ObligationCause, PredicateObligation};
 
 pub trait TraitEngine<'tcx>: 'tcx {
     fn normalize_projection_type<'a, 'gcx>(
@@ -49,7 +49,7 @@
         infcx: &InferCtxt<'a, 'gcx, 'tcx>,
     ) -> Result<(), Vec<FulfillmentError<'tcx>>>;
 
-    fn pending_obligations(&self) -> Vec<PendingPredicateObligation<'tcx>>;
+    fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>>;
 }
 
 impl<'a, 'gcx, 'tcx> dyn TraitEngine<'tcx> {
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index dc42334..f76b312 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -827,10 +827,13 @@
             }
 
             ConstEvalFailure(ref err) => {
-                if let ::middle::const_val::ErrKind::TypeckError = *err.kind {
-                    return;
+                match err.struct_error(
+                    self.tcx.at(span),
+                    "could not evaluate constant expression",
+                ) {
+                    Some(err) => err,
+                    None => return,
                 }
-                err.struct_error(self.tcx, span, "constant expression")
             }
 
             Overflow => {
diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs
index 4447a2b..04396d7 100644
--- a/src/librustc/traits/fulfill.rs
+++ b/src/librustc/traits/fulfill.rs
@@ -12,8 +12,8 @@
 use mir::interpret::GlobalId;
 use ty::{self, Ty, TypeFoldable, ToPolyTraitRef, ToPredicate};
 use ty::error::ExpectedFound;
-use rustc_data_structures::obligation_forest::{ObligationForest, Error};
-use rustc_data_structures::obligation_forest::{ForestObligation, ObligationProcessor};
+use rustc_data_structures::obligation_forest::{Error, ForestObligation, ObligationForest};
+use rustc_data_structures::obligation_forest::{ObligationProcessor, ProcessResult};
 use std::marker::PhantomData;
 use hir::def_id::DefId;
 use middle::const_val::{ConstEvalErr, ErrKind};
@@ -241,8 +241,8 @@
         self.select(&mut selcx)
     }
 
-    fn pending_obligations(&self) -> Vec<PendingPredicateObligation<'tcx>> {
-        self.predicates.pending_obligations()
+    fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>> {
+        self.predicates.map_pending_obligations(|o| o.obligation.clone())
     }
 }
 
@@ -251,19 +251,280 @@
     register_region_obligations: bool
 }
 
+fn mk_pending(os: Vec<PredicateObligation<'tcx>>) -> Vec<PendingPredicateObligation<'tcx>> {
+    os.into_iter().map(|o| PendingPredicateObligation {
+        obligation: o,
+        stalled_on: vec![]
+    }).collect()
+}
+
 impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx, 'tcx> {
     type Obligation = PendingPredicateObligation<'tcx>;
     type Error = FulfillmentErrorCode<'tcx>;
 
+    /// Processes a predicate obligation and returns either:
+    /// - `Changed(v)` if the predicate is true, presuming that `v` are also true
+    /// - `Unchanged` if we don't have enough info to be sure
+    /// - `Error(e)` if the predicate does not hold
+    ///
+    /// This is always inlined, despite its size, because it has a single
+    /// callsite and it is called *very* frequently.
+    #[inline(always)]
     fn process_obligation(&mut self,
-                          obligation: &mut Self::Obligation)
-                          -> Result<Option<Vec<Self::Obligation>>, Self::Error>
+                          pending_obligation: &mut Self::Obligation)
+                          -> ProcessResult<Self::Obligation, Self::Error>
     {
-        process_predicate(self.selcx, obligation, self.register_region_obligations)
-            .map(|os| os.map(|os| os.into_iter().map(|o| PendingPredicateObligation {
-                obligation: o,
-                stalled_on: vec![]
-            }).collect()))
+        // if we were stalled on some unresolved variables, first check
+        // whether any of them have been resolved; if not, don't bother
+        // doing more work yet
+        if !pending_obligation.stalled_on.is_empty() {
+            if pending_obligation.stalled_on.iter().all(|&ty| {
+                let resolved_ty = self.selcx.infcx().shallow_resolve(&ty);
+                resolved_ty == ty // nothing changed here
+            }) {
+                debug!("process_predicate: pending obligation {:?} still stalled on {:?}",
+                       self.selcx.infcx()
+                           .resolve_type_vars_if_possible(&pending_obligation.obligation),
+                       pending_obligation.stalled_on);
+                return ProcessResult::Unchanged;
+            }
+            pending_obligation.stalled_on = vec![];
+        }
+
+        let obligation = &mut pending_obligation.obligation;
+
+        if obligation.predicate.has_infer_types() {
+            obligation.predicate =
+                self.selcx.infcx().resolve_type_vars_if_possible(&obligation.predicate);
+        }
+
+        match obligation.predicate {
+            ty::Predicate::Trait(ref data) => {
+                let trait_obligation = obligation.with(data.clone());
+
+                if data.is_global() && !data.has_late_bound_regions() {
+                    // no type variables present, can use evaluation for better caching.
+                    // FIXME: consider caching errors too.
+                    if self.selcx.infcx().predicate_must_hold(&obligation) {
+                        debug!("selecting trait `{:?}` at depth {} evaluated to holds",
+                               data, obligation.recursion_depth);
+                        return ProcessResult::Changed(vec![])
+                    }
+                }
+
+                match self.selcx.select(&trait_obligation) {
+                    Ok(Some(vtable)) => {
+                        debug!("selecting trait `{:?}` at depth {} yielded Ok(Some)",
+                               data, obligation.recursion_depth);
+                        ProcessResult::Changed(mk_pending(vtable.nested_obligations()))
+                    }
+                    Ok(None) => {
+                        debug!("selecting trait `{:?}` at depth {} yielded Ok(None)",
+                               data, obligation.recursion_depth);
+
+                        // This is a bit subtle: for the most part, the
+                        // only reason we can fail to make progress on
+                        // trait selection is because we don't have enough
+                        // information about the types in the trait. One
+                        // exception is that we sometimes haven't decided
+                        // what kind of closure a closure is. *But*, in
+                        // that case, it turns out, the type of the
+                        // closure will also change, because the closure
+                        // also includes references to its upvars as part
+                        // of its type, and those types are resolved at
+                        // the same time.
+                        //
+                        // FIXME(#32286) logic seems false if no upvars
+                        pending_obligation.stalled_on =
+                            trait_ref_type_vars(self.selcx, data.to_poly_trait_ref());
+
+                        debug!("process_predicate: pending obligation {:?} now stalled on {:?}",
+                               self.selcx.infcx().resolve_type_vars_if_possible(obligation),
+                               pending_obligation.stalled_on);
+
+                        ProcessResult::Unchanged
+                    }
+                    Err(selection_err) => {
+                        info!("selecting trait `{:?}` at depth {} yielded Err",
+                              data, obligation.recursion_depth);
+
+                        ProcessResult::Error(CodeSelectionError(selection_err))
+                    }
+                }
+            }
+
+            ty::Predicate::RegionOutlives(ref binder) => {
+                match self.selcx.infcx().region_outlives_predicate(&obligation.cause, binder) {
+                    Ok(()) => ProcessResult::Changed(vec![]),
+                    Err(_) => ProcessResult::Error(CodeSelectionError(Unimplemented)),
+                }
+            }
+
+            ty::Predicate::TypeOutlives(ref binder) => {
+                // Check if there are higher-ranked regions.
+                match binder.no_late_bound_regions() {
+                    // If there are, inspect the underlying type further.
+                    None => {
+                        // Convert from `Binder<OutlivesPredicate<Ty, Region>>` to `Binder<Ty>`.
+                        let binder = binder.map_bound_ref(|pred| pred.0);
+
+                        // Check if the type has any bound regions.
+                        match binder.no_late_bound_regions() {
+                            // If so, this obligation is an error (for now). Eventually we should be
+                            // able to support additional cases here, like `for<'a> &'a str: 'a`.
+                            None => {
+                                ProcessResult::Error(CodeSelectionError(Unimplemented))
+                            }
+                            // Otherwise, we have something of the form
+                            // `for<'a> T: 'a where 'a not in T`, which we can treat as
+                            // `T: 'static`.
+                            Some(t_a) => {
+                                let r_static = self.selcx.tcx().types.re_static;
+                                if self.register_region_obligations {
+                                    self.selcx.infcx().register_region_obligation(
+                                        obligation.cause.body_id,
+                                        RegionObligation {
+                                            sup_type: t_a,
+                                            sub_region: r_static,
+                                            cause: obligation.cause.clone(),
+                                        });
+                                }
+                                ProcessResult::Changed(vec![])
+                            }
+                        }
+                    }
+                    // If there aren't, register the obligation.
+                    Some(ty::OutlivesPredicate(t_a, r_b)) => {
+                        if self.register_region_obligations {
+                            self.selcx.infcx().register_region_obligation(
+                                obligation.cause.body_id,
+                                RegionObligation {
+                                    sup_type: t_a,
+                                    sub_region: r_b,
+                                    cause: obligation.cause.clone()
+                                });
+                        }
+                        ProcessResult::Changed(vec![])
+                    }
+                }
+            }
+
+            ty::Predicate::Projection(ref data) => {
+                let project_obligation = obligation.with(data.clone());
+                match project::poly_project_and_unify_type(self.selcx, &project_obligation) {
+                    Ok(None) => {
+                        let tcx = self.selcx.tcx();
+                        pending_obligation.stalled_on =
+                            trait_ref_type_vars(self.selcx, data.to_poly_trait_ref(tcx));
+                        ProcessResult::Unchanged
+                    }
+                    Ok(Some(os)) => ProcessResult::Changed(mk_pending(os)),
+                    Err(e) => ProcessResult::Error(CodeProjectionError(e))
+                }
+            }
+
+            ty::Predicate::ObjectSafe(trait_def_id) => {
+                if !self.selcx.tcx().is_object_safe(trait_def_id) {
+                    ProcessResult::Error(CodeSelectionError(Unimplemented))
+                } else {
+                    ProcessResult::Changed(vec![])
+                }
+            }
+
+            ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
+                match self.selcx.infcx().closure_kind(closure_def_id, closure_substs) {
+                    Some(closure_kind) => {
+                        if closure_kind.extends(kind) {
+                            ProcessResult::Changed(vec![])
+                        } else {
+                            ProcessResult::Error(CodeSelectionError(Unimplemented))
+                        }
+                    }
+                    None => {
+                        ProcessResult::Unchanged
+                    }
+                }
+            }
+
+            ty::Predicate::WellFormed(ty) => {
+                match ty::wf::obligations(self.selcx.infcx(),
+                                          obligation.param_env,
+                                          obligation.cause.body_id,
+                                          ty, obligation.cause.span) {
+                    None => {
+                        pending_obligation.stalled_on = vec![ty];
+                        ProcessResult::Unchanged
+                    }
+                    Some(os) => ProcessResult::Changed(mk_pending(os))
+                }
+            }
+
+            ty::Predicate::Subtype(ref subtype) => {
+                match self.selcx.infcx().subtype_predicate(&obligation.cause,
+                                                           obligation.param_env,
+                                                           subtype) {
+                    None => {
+                        // None means that both are unresolved.
+                        pending_obligation.stalled_on = vec![subtype.skip_binder().a,
+                                                             subtype.skip_binder().b];
+                        ProcessResult::Unchanged
+                    }
+                    Some(Ok(ok)) => {
+                        ProcessResult::Changed(mk_pending(ok.obligations))
+                    }
+                    Some(Err(err)) => {
+                        let expected_found = ExpectedFound::new(subtype.skip_binder().a_is_expected,
+                                                                subtype.skip_binder().a,
+                                                                subtype.skip_binder().b);
+                        ProcessResult::Error(
+                            FulfillmentErrorCode::CodeSubtypeError(expected_found, err))
+                    }
+                }
+            }
+
+            ty::Predicate::ConstEvaluatable(def_id, substs) => {
+                match self.selcx.tcx().lift_to_global(&obligation.param_env) {
+                    None => {
+                        ProcessResult::Unchanged
+                    }
+                    Some(param_env) => {
+                        match self.selcx.tcx().lift_to_global(&substs) {
+                            Some(substs) => {
+                                let instance = ty::Instance::resolve(
+                                    self.selcx.tcx().global_tcx(),
+                                    param_env,
+                                    def_id,
+                                    substs,
+                                );
+                                if let Some(instance) = instance {
+                                    let cid = GlobalId {
+                                        instance,
+                                        promoted: None,
+                                    };
+                                    match self.selcx.tcx().at(obligation.cause.span)
+                                                          .const_eval(param_env.and(cid)) {
+                                        Ok(_) => ProcessResult::Changed(vec![]),
+                                        Err(err) => ProcessResult::Error(
+                                            CodeSelectionError(ConstEvalFailure(err)))
+                                    }
+                                } else {
+                                    ProcessResult::Error(
+                                        CodeSelectionError(ConstEvalFailure(ConstEvalErr {
+                                            span: obligation.cause.span,
+                                            kind: ErrKind::CouldNotResolve.into(),
+                                        }))
+                                    )
+                                }
+                            },
+                            None => {
+                                pending_obligation.stalled_on = substs.types().collect();
+                                ProcessResult::Unchanged
+                            }
+                        }
+                    }
+                }
+            }
+        }
     }
 
     fn process_backedge<'c, I>(&mut self, cycle: I,
@@ -292,264 +553,6 @@
      .collect()
 }
 
-/// Processes a predicate obligation and returns either:
-/// - `Ok(Some(v))` if the predicate is true, presuming that `v` are also true
-/// - `Ok(None)` if we don't have enough info to be sure
-/// - `Err` if the predicate does not hold
-fn process_predicate<'a, 'gcx, 'tcx>(
-    selcx: &mut SelectionContext<'a, 'gcx, 'tcx>,
-    pending_obligation: &mut PendingPredicateObligation<'tcx>,
-    register_region_obligations: bool)
-    -> Result<Option<Vec<PredicateObligation<'tcx>>>,
-              FulfillmentErrorCode<'tcx>>
-{
-    // if we were stalled on some unresolved variables, first check
-    // whether any of them have been resolved; if not, don't bother
-    // doing more work yet
-    if !pending_obligation.stalled_on.is_empty() {
-        if pending_obligation.stalled_on.iter().all(|&ty| {
-            let resolved_ty = selcx.infcx().shallow_resolve(&ty);
-            resolved_ty == ty // nothing changed here
-        }) {
-            debug!("process_predicate: pending obligation {:?} still stalled on {:?}",
-                   selcx.infcx().resolve_type_vars_if_possible(&pending_obligation.obligation),
-                   pending_obligation.stalled_on);
-            return Ok(None);
-        }
-        pending_obligation.stalled_on = vec![];
-    }
-
-    let obligation = &mut pending_obligation.obligation;
-
-    if obligation.predicate.has_infer_types() {
-        obligation.predicate = selcx.infcx().resolve_type_vars_if_possible(&obligation.predicate);
-    }
-
-    match obligation.predicate {
-        ty::Predicate::Trait(ref data) => {
-            let trait_obligation = obligation.with(data.clone());
-
-            if data.is_global() && !data.has_late_bound_regions() {
-                // no type variables present, can use evaluation for better caching.
-                // FIXME: consider caching errors too.
-                if selcx.infcx().predicate_must_hold(&obligation) {
-                    debug!("selecting trait `{:?}` at depth {} evaluated to holds",
-                           data, obligation.recursion_depth);
-                    return Ok(Some(vec![]))
-                }
-            }
-
-            match selcx.select(&trait_obligation) {
-                Ok(Some(vtable)) => {
-                    debug!("selecting trait `{:?}` at depth {} yielded Ok(Some)",
-                           data, obligation.recursion_depth);
-                    Ok(Some(vtable.nested_obligations()))
-                }
-                Ok(None) => {
-                    debug!("selecting trait `{:?}` at depth {} yielded Ok(None)",
-                           data, obligation.recursion_depth);
-
-                    // This is a bit subtle: for the most part, the
-                    // only reason we can fail to make progress on
-                    // trait selection is because we don't have enough
-                    // information about the types in the trait. One
-                    // exception is that we sometimes haven't decided
-                    // what kind of closure a closure is. *But*, in
-                    // that case, it turns out, the type of the
-                    // closure will also change, because the closure
-                    // also includes references to its upvars as part
-                    // of its type, and those types are resolved at
-                    // the same time.
-                    //
-                    // FIXME(#32286) logic seems false if no upvars
-                    pending_obligation.stalled_on =
-                        trait_ref_type_vars(selcx, data.to_poly_trait_ref());
-
-                    debug!("process_predicate: pending obligation {:?} now stalled on {:?}",
-                           selcx.infcx().resolve_type_vars_if_possible(obligation),
-                           pending_obligation.stalled_on);
-
-                    Ok(None)
-                }
-                Err(selection_err) => {
-                    info!("selecting trait `{:?}` at depth {} yielded Err",
-                          data, obligation.recursion_depth);
-
-                    Err(CodeSelectionError(selection_err))
-                }
-            }
-        }
-
-        ty::Predicate::RegionOutlives(ref binder) => {
-            match selcx.infcx().region_outlives_predicate(&obligation.cause, binder) {
-                Ok(()) => Ok(Some(Vec::new())),
-                Err(_) => Err(CodeSelectionError(Unimplemented)),
-            }
-        }
-
-        ty::Predicate::TypeOutlives(ref binder) => {
-            // Check if there are higher-ranked regions.
-            match binder.no_late_bound_regions() {
-                // If there are, inspect the underlying type further.
-                None => {
-                    // Convert from `Binder<OutlivesPredicate<Ty, Region>>` to `Binder<Ty>`.
-                    let binder = binder.map_bound_ref(|pred| pred.0);
-
-                    // Check if the type has any bound regions.
-                    match binder.no_late_bound_regions() {
-                        // If so, this obligation is an error (for now). Eventually we should be
-                        // able to support additional cases here, like `for<'a> &'a str: 'a`.
-                        None => {
-                            Err(CodeSelectionError(Unimplemented))
-                        }
-                        // Otherwise, we have something of the form
-                        // `for<'a> T: 'a where 'a not in T`, which we can treat as `T: 'static`.
-                        Some(t_a) => {
-                            let r_static = selcx.tcx().types.re_static;
-                            if register_region_obligations {
-                                selcx.infcx().register_region_obligation(
-                                    obligation.cause.body_id,
-                                    RegionObligation {
-                                        sup_type: t_a,
-                                        sub_region: r_static,
-                                        cause: obligation.cause.clone(),
-                                    });
-                            }
-                            Ok(Some(vec![]))
-                        }
-                    }
-                }
-                // If there aren't, register the obligation.
-                Some(ty::OutlivesPredicate(t_a, r_b)) => {
-                    if register_region_obligations {
-                        selcx.infcx().register_region_obligation(
-                            obligation.cause.body_id,
-                            RegionObligation {
-                                sup_type: t_a,
-                                sub_region: r_b,
-                                cause: obligation.cause.clone()
-                            });
-                    }
-                    Ok(Some(vec![]))
-                }
-            }
-        }
-
-        ty::Predicate::Projection(ref data) => {
-            let project_obligation = obligation.with(data.clone());
-            match project::poly_project_and_unify_type(selcx, &project_obligation) {
-                Ok(None) => {
-                    let tcx = selcx.tcx();
-                    pending_obligation.stalled_on =
-                        trait_ref_type_vars(selcx, data.to_poly_trait_ref(tcx));
-                    Ok(None)
-                }
-                Ok(v) => Ok(v),
-                Err(e) => Err(CodeProjectionError(e))
-            }
-        }
-
-        ty::Predicate::ObjectSafe(trait_def_id) => {
-            if !selcx.tcx().is_object_safe(trait_def_id) {
-                Err(CodeSelectionError(Unimplemented))
-            } else {
-                Ok(Some(Vec::new()))
-            }
-        }
-
-        ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => {
-            match selcx.infcx().closure_kind(closure_def_id, closure_substs) {
-                Some(closure_kind) => {
-                    if closure_kind.extends(kind) {
-                        Ok(Some(vec![]))
-                    } else {
-                        Err(CodeSelectionError(Unimplemented))
-                    }
-                }
-                None => {
-                    Ok(None)
-                }
-            }
-        }
-
-        ty::Predicate::WellFormed(ty) => {
-            match ty::wf::obligations(selcx.infcx(),
-                                      obligation.param_env,
-                                      obligation.cause.body_id,
-                                      ty, obligation.cause.span) {
-                None => {
-                    pending_obligation.stalled_on = vec![ty];
-                    Ok(None)
-                }
-                s => Ok(s)
-            }
-        }
-
-        ty::Predicate::Subtype(ref subtype) => {
-            match selcx.infcx().subtype_predicate(&obligation.cause,
-                                                  obligation.param_env,
-                                                  subtype) {
-                None => {
-                    // none means that both are unresolved
-                    pending_obligation.stalled_on = vec![subtype.skip_binder().a,
-                                                         subtype.skip_binder().b];
-                    Ok(None)
-                }
-                Some(Ok(ok)) => {
-                    Ok(Some(ok.obligations))
-                }
-                Some(Err(err)) => {
-                    let expected_found = ExpectedFound::new(subtype.skip_binder().a_is_expected,
-                                                            subtype.skip_binder().a,
-                                                            subtype.skip_binder().b);
-                    Err(FulfillmentErrorCode::CodeSubtypeError(expected_found, err))
-                }
-            }
-        }
-
-        ty::Predicate::ConstEvaluatable(def_id, substs) => {
-            match selcx.tcx().lift_to_global(&obligation.param_env) {
-                None => {
-                    Ok(None)
-                }
-                Some(param_env) => {
-                    match selcx.tcx().lift_to_global(&substs) {
-                        Some(substs) => {
-                            let instance = ty::Instance::resolve(
-                                selcx.tcx().global_tcx(),
-                                param_env,
-                                def_id,
-                                substs,
-                            );
-                            if let Some(instance) = instance {
-                                let cid = GlobalId {
-                                    instance,
-                                    promoted: None,
-                                };
-                                match selcx.tcx().at(obligation.cause.span)
-                                                 .const_eval(param_env.and(cid)) {
-                                    Ok(_) => Ok(Some(vec![])),
-                                    Err(err) => Err(CodeSelectionError(ConstEvalFailure(err)))
-                                }
-                            } else {
-                                Err(CodeSelectionError(ConstEvalFailure(ConstEvalErr {
-                                    span: obligation.cause.span,
-                                    kind: ErrKind::UnimplementedConstVal("could not resolve")
-                                        .into(),
-                                })))
-                            }
-                        },
-                        None => {
-                            pending_obligation.stalled_on = substs.types().collect();
-                            Ok(None)
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-
 fn to_fulfillment_error<'tcx>(
     error: Error<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>>)
     -> FulfillmentError<'tcx>
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index 3bd4e11..761de00 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -648,13 +648,8 @@
 
     let predicates: Vec<_> =
         util::elaborate_predicates(tcx, unnormalized_env.caller_bounds.to_vec())
-        .filter(|p| !p.is_global() || p.has_late_bound_regions()) // (*)
         .collect();
 
-    // (*) FIXME(#50825) This shouldn't be needed.
-    // Removing the bounds here stopped them from being prefered in selection.
-    // See the issue-50825 ui tests for examples
-
     debug!("normalize_param_env_or_error: elaborated-predicates={:?}",
            predicates);
 
@@ -996,8 +991,8 @@
     }
 }
 
-pub fn provide(providers: &mut ty::maps::Providers) {
-    *providers = ty::maps::Providers {
+pub fn provide(providers: &mut ty::query::Providers) {
+    *providers = ty::query::Providers {
         is_object_safe: object_safety::is_object_safe_provider,
         specialization_graph_of: specialize::specialization_graph_provider,
         specializes: specialize::specializes,
diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs
index c6b1d94..82f3517 100644
--- a/src/librustc/traits/project.rs
+++ b/src/librustc/traits/project.rs
@@ -146,7 +146,7 @@
         // was not used). On other paths, it is not assigned,
         // and hence if those paths *could* reach the code that
         // comes after the match, this fn would not compile.
-        let convert_to_ambigious;
+        let convert_to_ambiguous;
 
         match self {
             None => {
@@ -169,10 +169,10 @@
                 // clauses are the safer choice. See the comment on
                 // `select::SelectionCandidate` and #21974 for more details.
                 match (current, candidate) {
-                    (ParamEnv(..), ParamEnv(..)) => convert_to_ambigious = (),
+                    (ParamEnv(..), ParamEnv(..)) => convert_to_ambiguous = (),
                     (ParamEnv(..), _) => return false,
                     (_, ParamEnv(..)) => { unreachable!(); }
-                    (_, _) => convert_to_ambigious = (),
+                    (_, _) => convert_to_ambiguous = (),
                 }
             }
 
@@ -183,7 +183,7 @@
 
         // We only ever get here when we moved from a single candidate
         // to ambiguous.
-        let () = convert_to_ambigious;
+        let () = convert_to_ambiguous;
         *self = Ambiguous;
         false
     }
diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs
index 1e9e9c0..d0ae0bd 100644
--- a/src/librustc/traits/query/normalize.rs
+++ b/src/librustc/traits/query/normalize.rs
@@ -33,7 +33,7 @@
     /// normalized. If you don't care about regions, you should prefer
     /// `normalize_erasing_regions`, which is more efficient.
     ///
-    /// If the normalization succeeds and is unambigious, returns back
+    /// If the normalization succeeds and is unambiguous, returns back
     /// the normalized value along with various outlives relations (in
     /// the form of obligations that must be discharged).
     ///
@@ -123,6 +123,11 @@
                         let generic_ty = self.tcx().type_of(def_id);
                         let concrete_ty = generic_ty.subst(self.tcx(), substs);
                         self.anon_depth += 1;
+                        if concrete_ty == ty {
+                            println!("generic_ty: {:#?}", generic_ty);
+                            println!("substs {:#?}", substs);
+                        }
+                        assert_ne!(concrete_ty, ty, "infinite recursion");
                         let folded_ty = self.fold_ty(concrete_ty);
                         self.anon_depth -= 1;
                         folded_ty
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 7a52a5c..08af805 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -2011,9 +2011,6 @@
     // attempt to evaluate recursive bounds to see if they are
     // satisfied.
 
-    /// Returns true if `candidate_i` should be dropped in favor of
-    /// `candidate_j`.  Generally speaking we will drop duplicate
-    /// candidates and prefer where-clause candidates.
     /// Returns true if `victim` should be dropped in favor of
     /// `other`.  Generally speaking we will drop duplicate
     /// candidates and prefer where-clause candidates.
@@ -2025,13 +2022,19 @@
         other: &EvaluatedCandidate<'tcx>)
         -> bool
     {
+        // Check if a bound would previously have been removed when normalizing
+        // the param_env so that it can be given the lowest priority. See
+        // #50825 for the motivation for this.
+        let is_global = |cand: &ty::PolyTraitRef<'_>| {
+            cand.is_global() && !cand.has_late_bound_regions()
+        };
+
         if victim.candidate == other.candidate {
             return true;
         }
 
         match other.candidate {
-            ObjectCandidate |
-            ParamCandidate(_) | ProjectionCandidate => match victim.candidate {
+            ParamCandidate(ref cand) => match victim.candidate {
                 AutoImplCandidate(..) => {
                     bug!(
                         "default implementations shouldn't be recorded \
@@ -2044,8 +2047,33 @@
                 BuiltinObjectCandidate |
                 BuiltinUnsizeCandidate |
                 BuiltinCandidate { .. } => {
-                    // We have a where-clause so don't go around looking
-                    // for impls.
+                    // Global bounds from the where clause should be ignored
+                    // here (see issue #50825). Otherwise, we have a where
+                    // clause so don't go around looking for impls.
+                    !is_global(cand)
+                }
+                ObjectCandidate |
+                ProjectionCandidate => {
+                    // Arbitrarily give param candidates priority
+                    // over projection and object candidates.
+                    !is_global(cand)
+                },
+                ParamCandidate(..) => false,
+            },
+            ObjectCandidate |
+            ProjectionCandidate => match victim.candidate {
+                AutoImplCandidate(..) => {
+                    bug!(
+                        "default implementations shouldn't be recorded \
+                         when there are other valid candidates");
+                }
+                ImplCandidate(..) |
+                ClosureCandidate |
+                GeneratorCandidate |
+                FnPointerCandidate |
+                BuiltinObjectCandidate |
+                BuiltinUnsizeCandidate |
+                BuiltinCandidate { .. } => {
                     true
                 }
                 ObjectCandidate |
@@ -2054,22 +2082,44 @@
                     // over projection and object candidates.
                     true
                 },
-                ParamCandidate(..) => false,
+                ParamCandidate(ref cand) => is_global(cand),
             },
             ImplCandidate(other_def) => {
                 // See if we can toss out `victim` based on specialization.
                 // This requires us to know *for sure* that the `other` impl applies
                 // i.e. EvaluatedToOk:
                 if other.evaluation == EvaluatedToOk {
-                    if let ImplCandidate(victim_def) = victim.candidate {
-                        let tcx = self.tcx().global_tcx();
-                        return tcx.specializes((other_def, victim_def)) ||
-                            tcx.impls_are_allowed_to_overlap(other_def, victim_def);
+                    match victim.candidate {
+                        ImplCandidate(victim_def) => {
+                            let tcx = self.tcx().global_tcx();
+                            return tcx.specializes((other_def, victim_def)) ||
+                                tcx.impls_are_allowed_to_overlap(other_def, victim_def);
+                        }
+                        ParamCandidate(ref cand) => {
+                            // Prefer the impl to a global where clause candidate.
+                            return is_global(cand);
+                        }
+                        _ => ()
                     }
                 }
 
                 false
             },
+            ClosureCandidate |
+            GeneratorCandidate |
+            FnPointerCandidate |
+            BuiltinObjectCandidate |
+            BuiltinUnsizeCandidate |
+            BuiltinCandidate { .. } => {
+                match victim.candidate {
+                    ParamCandidate(ref cand) => {
+                        // Prefer these to a global where-clause bound
+                        // (see issue #50825)
+                        is_global(cand) && other.evaluation == EvaluatedToOk
+                    }
+                    _ => false,
+                }
+            }
             _ => false
         }
     }
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 68f55b4..6cbf4fa 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -46,7 +46,7 @@
 use ty::TypeVariants::*;
 use ty::GenericParamDefKind;
 use ty::layout::{LayoutDetails, TargetDataLayout};
-use ty::maps;
+use ty::query;
 use ty::steal::Steal;
 use ty::BindingMode;
 use ty::CanonicalTy;
@@ -58,7 +58,7 @@
                                            StableVec};
 use arena::{TypedArena, SyncDroplessArena};
 use rustc_data_structures::indexed_vec::IndexVec;
-use rustc_data_structures::sync::{Lrc, Lock};
+use rustc_data_structures::sync::{self, Lrc, Lock, WorkerLocal};
 use std::any::Any;
 use std::borrow::Borrow;
 use std::cmp::Ordering;
@@ -80,14 +80,14 @@
 use hir;
 
 pub struct AllArenas<'tcx> {
-    pub global: GlobalArenas<'tcx>,
+    pub global: WorkerLocal<GlobalArenas<'tcx>>,
     pub interner: SyncDroplessArena,
 }
 
 impl<'tcx> AllArenas<'tcx> {
     pub fn new() -> Self {
         AllArenas {
-            global: GlobalArenas::new(),
+            global: WorkerLocal::new(|_| GlobalArenas::new()),
             interner: SyncDroplessArena::new(),
         }
     }
@@ -427,6 +427,10 @@
     /// its where clauses and parameter types. These are then
     /// read-again by borrowck.
     pub free_region_map: FreeRegionMap<'tcx>,
+
+    /// All the existential types that are restricted to concrete types
+    /// by this function
+    pub concrete_existential_types: FxHashMap<DefId, Ty<'tcx>>,
 }
 
 impl<'tcx> TypeckTables<'tcx> {
@@ -449,6 +453,7 @@
             used_trait_imports: Lrc::new(DefIdSet()),
             tainted_by_errors: false,
             free_region_map: FreeRegionMap::new(),
+            concrete_existential_types: FxHashMap(),
         }
     }
 
@@ -746,6 +751,7 @@
             ref used_trait_imports,
             tainted_by_errors,
             ref free_region_map,
+            ref concrete_existential_types,
         } = *self;
 
         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
@@ -786,6 +792,7 @@
             used_trait_imports.hash_stable(hcx, hasher);
             tainted_by_errors.hash_stable(hcx, hasher);
             free_region_map.hash_stable(hcx, hasher);
+            concrete_existential_types.hash_stable(hcx, hasher);
         })
     }
 }
@@ -854,7 +861,7 @@
 }
 
 pub struct GlobalCtxt<'tcx> {
-    global_arenas: &'tcx GlobalArenas<'tcx>,
+    global_arenas: &'tcx WorkerLocal<GlobalArenas<'tcx>>,
     global_interners: CtxtInterners<'tcx>,
 
     cstore: &'tcx CrateStoreDyn,
@@ -863,11 +870,6 @@
 
     pub dep_graph: DepGraph,
 
-    /// This provides access to the incr. comp. on-disk cache for query results.
-    /// Do not access this directly. It is only meant to be used by
-    /// `DepGraph::try_mark_green()` and the query infrastructure in `ty::maps`.
-    pub(crate) on_disk_query_result_cache: maps::OnDiskCache<'tcx>,
-
     /// Common types, pre-interned for your convenience.
     pub types: CommonTypes<'tcx>,
 
@@ -886,7 +888,7 @@
     /// as well as all upstream crates. Only populated in incremental mode.
     pub def_path_hash_to_def_id: Option<FxHashMap<DefPathHash, DefId>>,
 
-    pub maps: maps::Maps<'tcx>,
+    pub(crate) queries: query::Queries<'tcx>,
 
     // Records the free variables refrenced by every closure
     // expression. Do not track deps for this, just recompute it from
@@ -1074,12 +1076,12 @@
     /// reference to the context, to allow formatting values that need it.
     pub fn create_and_enter<F, R>(s: &'tcx Session,
                                   cstore: &'tcx CrateStoreDyn,
-                                  local_providers: ty::maps::Providers<'tcx>,
-                                  extern_providers: ty::maps::Providers<'tcx>,
+                                  local_providers: ty::query::Providers<'tcx>,
+                                  extern_providers: ty::query::Providers<'tcx>,
                                   arenas: &'tcx AllArenas<'tcx>,
                                   resolutions: ty::Resolutions,
                                   hir: hir_map::Map<'tcx>,
-                                  on_disk_query_result_cache: maps::OnDiskCache<'tcx>,
+                                  on_disk_query_result_cache: query::OnDiskCache<'tcx>,
                                   crate_name: &str,
                                   tx: mpsc::Sender<Box<dyn Any + Send>>,
                                   output_filenames: &OutputFilenames,
@@ -1144,7 +1146,6 @@
             global_arenas: &arenas.global,
             global_interners: interners,
             dep_graph: dep_graph.clone(),
-            on_disk_query_result_cache,
             types: common_types,
             trait_map,
             export_map: resolutions.export_map.into_iter().map(|(k, v)| {
@@ -1165,7 +1166,7 @@
                     .collect(),
             hir,
             def_path_hash_to_def_id,
-            maps: maps::Maps::new(providers),
+            queries: query::Queries::new(providers, on_disk_query_result_cache),
             rcache: Lock::new(FxHashMap()),
             selection_cache: traits::SelectionCache::new(),
             evaluation_cache: traits::EvaluationCache::new(),
@@ -1179,6 +1180,8 @@
             output_filenames: Arc::new(output_filenames.clone()),
         };
 
+        sync::assert_send_val(&gcx);
+
         tls::enter_global(gcx, f)
     }
 
@@ -1341,7 +1344,7 @@
                                            -> Result<(), E::Error>
         where E: ty::codec::TyEncoder
     {
-        self.on_disk_query_result_cache.serialize(self.global_tcx(), encoder)
+        self.queries.on_disk_cache.serialize(self.global_tcx(), encoder)
     }
 
     /// If true, we should use a naive AST walk to determine if match
@@ -1697,16 +1700,21 @@
 pub mod tls {
     use super::{GlobalCtxt, TyCtxt};
 
-    use std::cell::Cell;
     use std::fmt;
     use std::mem;
     use syntax_pos;
-    use ty::maps;
+    use ty::query;
     use errors::{Diagnostic, TRACK_DIAGNOSTICS};
     use rustc_data_structures::OnDrop;
-    use rustc_data_structures::sync::Lrc;
+    use rustc_data_structures::sync::{self, Lrc, Lock};
     use dep_graph::OpenTask;
 
+    #[cfg(not(parallel_queries))]
+    use std::cell::Cell;
+
+    #[cfg(parallel_queries)]
+    use rayon_core;
+
     /// This is the implicit state of rustc. It contains the current
     /// TyCtxt and query. It is updated when creating a local interner or
     /// executing a new query. Whenever there's a TyCtxt value available
@@ -1719,8 +1727,8 @@
         pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
 
         /// The current query job, if any. This is updated by start_job in
-        /// ty::maps::plumbing when executing a query
-        pub query: Option<Lrc<maps::QueryJob<'gcx>>>,
+        /// ty::query::plumbing when executing a query
+        pub query: Option<Lrc<query::QueryJob<'gcx>>>,
 
         /// Used to prevent layout from recursing too deeply.
         pub layout_depth: usize,
@@ -1730,9 +1738,29 @@
         pub task: &'a OpenTask,
     }
 
-    // A thread local value which stores a pointer to the current ImplicitCtxt
+    /// Sets Rayon's thread local variable which is preserved for Rayon jobs
+    /// to `value` during the call to `f`. It is restored to its previous value after.
+    /// This is used to set the pointer to the new ImplicitCtxt.
+    #[cfg(parallel_queries)]
+    fn set_tlv<F: FnOnce() -> R, R>(value: usize, f: F) -> R {
+        rayon_core::tlv::with(value, f)
+    }
+
+    /// Gets Rayon's thread local variable which is preserved for Rayon jobs.
+    /// This is used to get the pointer to the current ImplicitCtxt.
+    #[cfg(parallel_queries)]
+    fn get_tlv() -> usize {
+        rayon_core::tlv::get()
+    }
+
+    /// A thread local variable which stores a pointer to the current ImplicitCtxt
+    #[cfg(not(parallel_queries))]
     thread_local!(static TLV: Cell<usize> = Cell::new(0));
 
+    /// Sets TLV to `value` during the call to `f`.
+    /// It is restored to its previous value after.
+    /// This is used to set the pointer to the new ImplicitCtxt.
+    #[cfg(not(parallel_queries))]
     fn set_tlv<F: FnOnce() -> R, R>(value: usize, f: F) -> R {
         let old = get_tlv();
         let _reset = OnDrop(move || TLV.with(|tlv| tlv.set(old)));
@@ -1740,6 +1768,8 @@
         f()
     }
 
+    /// This is used to get the pointer to the current ImplicitCtxt.
+    #[cfg(not(parallel_queries))]
     fn get_tlv() -> usize {
         TLV.with(|tlv| tlv.get())
     }
@@ -1808,6 +1838,15 @@
         where F: for<'a> FnOnce(TyCtxt<'a, 'gcx, 'gcx>) -> R
     {
         with_thread_locals(|| {
+            // Update GCX_PTR to indicate there's a GlobalCtxt available
+            GCX_PTR.with(|lock| {
+                *lock.lock() = gcx as *const _ as usize;
+            });
+            // Set GCX_PTR back to 0 when we exit
+            let _on_drop = OnDrop(move || {
+                GCX_PTR.with(|lock| *lock.lock() = 0);
+            });
+
             let tcx = TyCtxt {
                 gcx,
                 interners: &gcx.global_interners,
@@ -1824,6 +1863,32 @@
         })
     }
 
+    /// Stores a pointer to the GlobalCtxt if one is available.
+    /// This is used to access the GlobalCtxt in the deadlock handler
+    /// given to Rayon.
+    scoped_thread_local!(pub static GCX_PTR: Lock<usize>);
+
+    /// Creates a TyCtxt and ImplicitCtxt based on the GCX_PTR thread local.
+    /// This is used in the deadlock handler.
+    pub unsafe fn with_global<F, R>(f: F) -> R
+        where F: for<'a, 'gcx, 'tcx> FnOnce(TyCtxt<'a, 'gcx, 'tcx>) -> R
+    {
+        let gcx = GCX_PTR.with(|lock| *lock.lock());
+        assert!(gcx != 0);
+        let gcx = &*(gcx as *const GlobalCtxt<'_>);
+        let tcx = TyCtxt {
+            gcx,
+            interners: &gcx.global_interners,
+        };
+        let icx = ImplicitCtxt {
+            query: None,
+            tcx,
+            layout_depth: 0,
+            task: &OpenTask::Ignore,
+        };
+        enter_context(&icx, |_| f(tcx))
+    }
+
     /// Allows access to the current ImplicitCtxt in a closure if one is available
     pub fn with_context_opt<F, R>(f: F) -> R
         where F: for<'a, 'gcx, 'tcx> FnOnce(Option<&ImplicitCtxt<'a, 'gcx, 'tcx>>) -> R
@@ -1832,6 +1897,10 @@
         if context == 0 {
             f(None)
         } else {
+            // We could get a ImplicitCtxt pointer from another thread.
+            // Ensure that ImplicitCtxt is Sync
+            sync::assert_sync::<ImplicitCtxt>();
+
             unsafe { f(Some(&*(context as *const ImplicitCtxt))) }
         }
     }
@@ -2446,7 +2515,7 @@
     pub fn intern_existential_predicates(self, eps: &[ExistentialPredicate<'tcx>])
         -> &'tcx Slice<ExistentialPredicate<'tcx>> {
         assert!(!eps.is_empty());
-        assert!(eps.windows(2).all(|w| w[0].cmp(self, &w[1]) != Ordering::Greater));
+        assert!(eps.windows(2).all(|w| w[0].stable_cmp(self, &w[1]) != Ordering::Greater));
         self._intern_existential_predicates(eps)
     }
 
@@ -2724,7 +2793,7 @@
     }
 }
 
-pub fn provide(providers: &mut ty::maps::Providers) {
+pub fn provide(providers: &mut ty::query::Providers) {
     // FIXME(#44234) - almost all of these queries have no sub-queries and
     // therefore no actual inputs, they're just reading tables calculated in
     // resolve! Does this work? Unsure! That's what the issue is about
diff --git a/src/librustc/ty/erase_regions.rs b/src/librustc/ty/erase_regions.rs
index f483b4c..2fb2154 100644
--- a/src/librustc/ty/erase_regions.rs
+++ b/src/librustc/ty/erase_regions.rs
@@ -11,8 +11,8 @@
 use ty::{self, Ty, TyCtxt};
 use ty::fold::{TypeFolder, TypeFoldable};
 
-pub(super) fn provide(providers: &mut ty::maps::Providers) {
-    *providers = ty::maps::Providers {
+pub(super) fn provide(providers: &mut ty::query::Providers) {
+    *providers = ty::query::Providers {
         erase_regions_ty,
         ..*providers
     };
diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs
index ebbdc92..e3fbadc 100644
--- a/src/librustc/ty/flags.rs
+++ b/src/librustc/ty/flags.rs
@@ -24,7 +24,7 @@
     fn new() -> FlagComputation {
         FlagComputation {
             flags: TypeFlags::empty(),
-            outer_exclusive_binder: ty::DebruijnIndex::INNERMOST,
+            outer_exclusive_binder: ty::INNERMOST,
         }
     }
 
@@ -60,7 +60,7 @@
         // a region binder, so subtract one from the region depth
         // within when adding the depth to `self`.
         let outer_exclusive_binder = computation.outer_exclusive_binder;
-        if outer_exclusive_binder > ty::DebruijnIndex::INNERMOST {
+        if outer_exclusive_binder > ty::INNERMOST {
             self.add_exclusive_binder(outer_exclusive_binder.shifted_out(1));
         } else {
             // otherwise, this binder captures nothing
diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs
index dea33ca..d459a6d 100644
--- a/src/librustc/ty/fold.rs
+++ b/src/librustc/ty/fold.rs
@@ -65,7 +65,7 @@
 
     /// True if `self` has any late-bound regions that are either
     /// bound by `binder` or bound by some binder outside of `binder`.
-    /// If `binder` is `ty::DebruijnIndex::INNERMOST`, this indicates whether
+    /// If `binder` is `ty::INNERMOST`, this indicates whether
     /// there are any late-bound regions that appear free.
     fn has_regions_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool {
         self.visit_with(&mut HasEscapingRegionsVisitor { outer_index: binder })
@@ -78,7 +78,7 @@
     }
 
     fn has_escaping_regions(&self) -> bool {
-        self.has_regions_bound_at_or_above(ty::DebruijnIndex::INNERMOST)
+        self.has_regions_bound_at_or_above(ty::INNERMOST)
     }
 
     fn has_type_flags(&self, flags: TypeFlags) -> bool {
@@ -246,7 +246,7 @@
               T: TypeFoldable<'tcx>,
     {
         value.visit_with(&mut RegionVisitor {
-            outer_index: ty::DebruijnIndex::INNERMOST,
+            outer_index: ty::INNERMOST,
             callback
         });
 
@@ -260,7 +260,7 @@
             /// ^          ^          ^     ^
             /// |          |          |     | here, would be shifted in 1
             /// |          |          | here, would be shifted in 2
-            /// |          | here, would be INNTERMOST shifted in by 1
+            /// |          | here, would be INNERMOST shifted in by 1
             /// | here, initially, binder would be INNERMOST
             /// ```
             ///
@@ -333,7 +333,7 @@
         RegionFolder {
             tcx,
             skipped_regions,
-            current_index: ty::DebruijnIndex::INNERMOST,
+            current_index: ty::INNERMOST,
             fold_region_fn,
         }
     }
@@ -495,7 +495,7 @@
         let mut counter = 0;
         Binder::bind(self.replace_late_bound_regions(sig, |_| {
             counter += 1;
-            self.mk_region(ty::ReLateBound(ty::DebruijnIndex::INNERMOST, ty::BrAnon(counter)))
+            self.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BrAnon(counter)))
         }).0)
     }
 }
@@ -507,7 +507,7 @@
     {
         RegionReplacer {
             tcx,
-            current_index: ty::DebruijnIndex::INNERMOST,
+            current_index: ty::INNERMOST,
             fld_r,
             map: BTreeMap::default()
         }
@@ -542,7 +542,7 @@
                     // that region should always use the INNERMOST
                     // debruijn index. Then we adjust it to the
                     // correct depth.
-                    assert_eq!(debruijn1, ty::DebruijnIndex::INNERMOST);
+                    assert_eq!(debruijn1, ty::INNERMOST);
                     self.tcx.mk_region(ty::ReLateBound(debruijn, br))
                 } else {
                     region
@@ -701,7 +701,7 @@
 impl LateBoundRegionsCollector {
     fn new(just_constrained: bool) -> Self {
         LateBoundRegionsCollector {
-            current_index: ty::DebruijnIndex::INNERMOST,
+            current_index: ty::INNERMOST,
             regions: FxHashSet(),
             just_constrained,
         }
diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs
index 87ace45..d858ba7 100644
--- a/src/librustc/ty/item_path.rs
+++ b/src/librustc/ty/item_path.rs
@@ -221,7 +221,8 @@
             data @ DefPathData::AnonConst |
             data @ DefPathData::MacroDef(..) |
             data @ DefPathData::ClosureExpr |
-            data @ DefPathData::ImplTrait |
+            data @ DefPathData::ExistentialImplTrait |
+            data @ DefPathData::UniversalImplTrait |
             data @ DefPathData::GlobalMetaData(..) => {
                 let parent_def_id = self.parent_def_id(def_id).unwrap();
                 self.push_item_path(buffer, parent_def_id);
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index 499398a..f5c2a0c 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -194,8 +194,8 @@
     })
 }
 
-pub fn provide(providers: &mut ty::maps::Providers) {
-    *providers = ty::maps::Providers {
+pub fn provide(providers: &mut ty::query::Providers) {
+    *providers = ty::query::Providers {
         layout_raw,
         ..*providers
     };
@@ -1481,7 +1481,7 @@
     }
 }
 
-impl<'a, 'tcx> LayoutOf for LayoutCx<'tcx, ty::maps::TyCtxtAt<'a, 'tcx, 'tcx>> {
+impl<'a, 'tcx> LayoutOf for LayoutCx<'tcx, ty::query::TyCtxtAt<'a, 'tcx, 'tcx>> {
     type Ty = Ty<'tcx>;
     type TyLayout = Result<TyLayout<'tcx>, LayoutError<'tcx>>;
 
@@ -1527,7 +1527,7 @@
     }
 }
 
-impl ty::maps::TyCtxtAt<'a, 'tcx, '_> {
+impl ty::query::TyCtxtAt<'a, 'tcx, '_> {
     /// Computes the layout of a type. Note that this implicitly
     /// executes in "reveal all" mode.
     #[inline]
diff --git a/src/librustc/ty/maps/job.rs b/src/librustc/ty/maps/job.rs
deleted file mode 100644
index 3b6af01..0000000
--- a/src/librustc/ty/maps/job.rs
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2017 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 rustc_data_structures::sync::{Lock, Lrc};
-use syntax_pos::Span;
-use ty::tls;
-use ty::maps::Query;
-use ty::maps::plumbing::CycleError;
-use ty::context::TyCtxt;
-use errors::Diagnostic;
-
-/// Indicates the state of a query for a given key in a query map
-pub(super) enum QueryResult<'tcx> {
-    /// An already executing query. The query job can be used to await for its completion
-    Started(Lrc<QueryJob<'tcx>>),
-
-    /// The query panicked. Queries trying to wait on this will raise a fatal error / silently panic
-    Poisoned,
-}
-
-/// A span and a query key
-#[derive(Clone, Debug)]
-pub struct QueryInfo<'tcx> {
-    /// The span for a reason this query was required
-    pub span: Span,
-    pub query: Query<'tcx>,
-}
-
-/// A object representing an active query job.
-pub struct QueryJob<'tcx> {
-    pub info: QueryInfo<'tcx>,
-
-    /// The parent query job which created this job and is implicitly waiting on it.
-    pub parent: Option<Lrc<QueryJob<'tcx>>>,
-
-    /// Diagnostic messages which are emitted while the query executes
-    pub diagnostics: Lock<Vec<Diagnostic>>,
-}
-
-impl<'tcx> QueryJob<'tcx> {
-    /// Creates a new query job
-    pub fn new(info: QueryInfo<'tcx>, parent: Option<Lrc<QueryJob<'tcx>>>) -> Self {
-        QueryJob {
-            diagnostics: Lock::new(Vec::new()),
-            info,
-            parent,
-        }
-    }
-
-    /// Awaits for the query job to complete.
-    ///
-    /// For single threaded rustc there's no concurrent jobs running, so if we are waiting for any
-    /// query that means that there is a query cycle, thus this always running a cycle error.
-    pub(super) fn await<'lcx>(
-        &self,
-        tcx: TyCtxt<'_, 'tcx, 'lcx>,
-        span: Span,
-    ) -> Result<(), CycleError<'tcx>> {
-        // Get the current executing query (waiter) and find the waitee amongst its parents
-        let mut current_job = tls::with_related_context(tcx, |icx| icx.query.clone());
-        let mut cycle = Vec::new();
-
-        while let Some(job) = current_job {
-            cycle.insert(0, job.info.clone());
-
-            if &*job as *const _ == self as *const _ {
-                // This is the end of the cycle
-                // The span entry we included was for the usage
-                // of the cycle itself, and not part of the cycle
-                // Replace it with the span which caused the cycle to form
-                cycle[0].span = span;
-                // Find out why the cycle itself was used
-                let usage = job.parent.as_ref().map(|parent| {
-                    (job.info.span, parent.info.query.clone())
-                });
-                return Err(CycleError { usage, cycle });
-            }
-
-            current_job = job.parent.clone();
-        }
-
-        panic!("did not find a cycle")
-    }
-
-    /// Signals to waiters that the query is complete.
-    ///
-    /// This does nothing for single threaded rustc,
-    /// as there are no concurrent jobs which could be waiting on us
-    pub fn signal_complete(&self) {}
-}
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 646c60c..e4296a0 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -60,7 +60,7 @@
 
 use hir;
 
-pub use self::sty::{Binder, CanonicalVar, DebruijnIndex};
+pub use self::sty::{Binder, CanonicalVar, DebruijnIndex, INNERMOST};
 pub use self::sty::{FnSig, GenSig, PolyFnSig, PolyGenSig};
 pub use self::sty::{InferTy, ParamTy, ProjectionTy, ExistentialPredicate};
 pub use self::sty::{ClosureSubsts, GeneratorSubsts, UpvarSubsts, TypeAndMut};
@@ -85,7 +85,7 @@
 
 pub use self::trait_def::TraitDef;
 
-pub use self::maps::queries;
+pub use self::query::queries;
 
 pub mod adjustment;
 pub mod binding;
@@ -100,8 +100,8 @@
 pub mod item_path;
 pub mod layout;
 pub mod _match;
-pub mod maps;
 pub mod outlives;
+pub mod query;
 pub mod relate;
 pub mod steal;
 pub mod subst;
@@ -270,7 +270,7 @@
     pub fn from_hir(visibility: &hir::Visibility, id: NodeId, tcx: TyCtxt) -> Self {
         match *visibility {
             hir::Public => Visibility::Public,
-            hir::Visibility::Crate => Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)),
+            hir::Visibility::Crate(_) => Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)),
             hir::Visibility::Restricted { ref path, .. } => match path.def {
                 // If there is no resolution, `resolve` will have already reported an error, so
                 // assume that the visibility is public to avoid reporting more privacy errors.
@@ -617,6 +617,8 @@
     opaque: OpaqueSliceContents,
 }
 
+unsafe impl<T: Sync> Sync for Slice<T> {}
+
 impl<T: Copy> Slice<T> {
     #[inline]
     fn from_arena<'tcx>(arena: &'tcx SyncDroplessArena, slice: &[T]) -> &'tcx Slice<T> {
@@ -2073,15 +2075,17 @@
                 } else {
                     info!("invalid enum discriminant: {:#?}", val);
                     ::middle::const_val::struct_error(
-                        tcx,
-                        tcx.def_span(expr_did),
+                        tcx.at(tcx.def_span(expr_did)),
                         "constant evaluation of enum discriminant resulted in non-integer",
                     ).emit();
                     None
                 }
             }
             Err(err) => {
-                err.report(tcx, tcx.def_span(expr_did), "enum discriminant");
+                err.report_as_error(
+                    tcx.at(tcx.def_span(expr_did)),
+                    "could not evaluate enum discriminant",
+                );
                 if !expr_did.is_local() {
                     span_bug!(tcx.def_span(expr_did),
                         "variant discriminant evaluation succeeded \
@@ -2171,7 +2175,7 @@
     /// Due to normalization being eager, this applies even if
     /// the associated type is behind a pointer, e.g. issue #31299.
     pub fn sized_constraint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> &'tcx [Ty<'tcx>] {
-        match tcx.try_get_query::<queries::adt_sized_constraint>(DUMMY_SP, self.did) {
+        match tcx.try_adt_sized_constraint(DUMMY_SP, self.did) {
             Ok(tys) => tys,
             Err(mut bug) => {
                 debug!("adt_sized_constraint: {:?} is recursive", self);
@@ -2853,6 +2857,12 @@
 fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                        def_id: DefId)
                        -> ParamEnv<'tcx> {
+
+    // The param_env of an existential type is its parent's param_env
+    if let Some(Def::Existential(_)) = tcx.describe_def(def_id) {
+        let parent = tcx.parent_def_id(def_id).expect("impl trait item w/o a parent");
+        return param_env(tcx, parent);
+    }
     // Compute the bounds on Self and the type parameters.
 
     let bounds = tcx.predicates_of(def_id).instantiate_identity(tcx);
@@ -2913,12 +2923,12 @@
     }
 }
 
-pub fn provide(providers: &mut ty::maps::Providers) {
+pub fn provide(providers: &mut ty::query::Providers) {
     context::provide(providers);
     erase_regions::provide(providers);
     layout::provide(providers);
     util::provide(providers);
-    *providers = ty::maps::Providers {
+    *providers = ty::query::Providers {
         associated_item,
         associated_item_def_ids,
         adt_sized_constraint,
diff --git a/src/librustc/ty/maps/README.md b/src/librustc/ty/query/README.md
similarity index 97%
rename from src/librustc/ty/maps/README.md
rename to src/librustc/ty/query/README.md
index 8207c18..ca6f0b7 100644
--- a/src/librustc/ty/maps/README.md
+++ b/src/librustc/ty/query/README.md
@@ -55,7 +55,7 @@
 using the `try_get` method, which looks roughly like this:
 
 ```rust
-use ty::maps::queries;
+use ty::query::queries;
 ...
 match queries::type_of::try_get(tcx, DUMMY_SP, self.did) {
   Ok(result) => {
@@ -207,7 +207,7 @@
 like:
 
 ```
-define_maps! { <'tcx>
+define_queries! { <'tcx>
     /// Records the type of every item.
     [] fn type_of: TypeOfItem(DefId) -> Ty<'tcx>,
 
@@ -235,7 +235,7 @@
   processed.
 - **Name of query:** the name of the query method
   (`tcx.type_of(..)`). Also used as the name of a struct
-  (`ty::maps::queries::type_of`) that will be generated to represent
+  (`ty::query::queries::type_of`) that will be generated to represent
   this query.
 - **Dep-node constructor:** indicates the constructor function that
   connects this query to incremental compilation. Typically, this is a
@@ -247,7 +247,7 @@
     bottom of the file. This is typically used when the query key is
     not a def-id, or just not the type that the dep-node expects.
 - **Query key type:** the type of the argument to this query.
-  This type must implement the `ty::maps::keys::Key` trait, which
+  This type must implement the `ty::query::keys::Key` trait, which
   defines (for example) how to map it to a crate, and so forth.
 - **Result type of query:** the type produced by this query. This type
   should (a) not use `RefCell` or other interior mutability and (b) be
@@ -260,14 +260,14 @@
 
 So, to add a query:
 
-- Add an entry to `define_maps!` using the format above.
+- Add an entry to `define_queries!` using the format above.
 - Possibly add a corresponding entry to the dep-node macro.
 - Link the provider by modifying the appropriate `provide` method;
   or add a new one if needed and ensure that `rustc_driver` is invoking it.
 
 #### Query structs and descriptions
 
-For each kind, the `define_maps` macro will generate a "query struct"
+For each kind, the `define_queries` macro will generate a "query struct"
 named after the query. This struct is a kind of a place-holder
 describing the query. Each such struct implements the
 `self::config::QueryConfig` trait, which has associated types for the
diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/query/config.rs
similarity index 96%
rename from src/librustc/ty/maps/config.rs
rename to src/librustc/ty/query/config.rs
index 19c97a9..cc00e9a 100644
--- a/src/librustc/ty/maps/config.rs
+++ b/src/librustc/ty/query/config.rs
@@ -15,9 +15,9 @@
 use traits::query::{CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal};
 use ty::{self, ParamEnvAnd, Ty, TyCtxt};
 use ty::subst::Substs;
-use ty::maps::queries;
-use ty::maps::Query;
-use ty::maps::QueryMap;
+use ty::query::queries;
+use ty::query::Query;
+use ty::query::QueryCache;
 
 use std::hash::Hash;
 use std::fmt::Debug;
@@ -26,18 +26,20 @@
 use rustc_data_structures::stable_hasher::HashStable;
 use ich::StableHashingContext;
 
-/// Query configuration and description traits.
+// Query configuration and description traits.
 
 pub trait QueryConfig<'tcx> {
     const NAME: &'static str;
 
     type Key: Eq + Hash + Clone + Debug;
     type Value: Clone + for<'a> HashStable<StableHashingContext<'a>>;
+}
 
+pub(super) trait QueryAccessors<'tcx>: QueryConfig<'tcx> {
     fn query(key: Self::Key) -> Query<'tcx>;
 
     // Don't use this method to access query results, instead use the methods on TyCtxt
-    fn query_map<'a>(tcx: TyCtxt<'a, 'tcx, '_>) -> &'a Lock<QueryMap<'tcx, Self>>;
+    fn query_cache<'a>(tcx: TyCtxt<'a, 'tcx, '_>) -> &'a Lock<QueryCache<'tcx, Self>>;
 
     fn to_dep_node(tcx: TyCtxt<'_, 'tcx, '_>, key: &Self::Key) -> DepNode;
 
@@ -47,7 +49,7 @@
     fn handle_cycle_error(tcx: TyCtxt<'_, 'tcx, '_>) -> Self::Value;
 }
 
-pub trait QueryDescription<'tcx>: QueryConfig<'tcx> {
+pub(super) trait QueryDescription<'tcx>: QueryAccessors<'tcx> {
     fn describe(tcx: TyCtxt, key: Self::Key) -> String;
 
     #[inline]
@@ -62,7 +64,7 @@
     }
 }
 
-impl<'tcx, M: QueryConfig<'tcx, Key=DefId>> QueryDescription<'tcx> for M {
+impl<'tcx, M: QueryAccessors<'tcx, Key=DefId>> QueryDescription<'tcx> for M {
     default fn describe(tcx: TyCtxt, def_id: DefId) -> String {
         if !tcx.sess.verbose() {
             format!("processing `{}`", tcx.item_path_str(def_id))
@@ -233,7 +235,7 @@
     fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                               id: SerializedDepNodeIndex)
                               -> Option<Self::Value> {
-        tcx.on_disk_query_result_cache.try_load_query_result(tcx, id).map(Ok)
+        tcx.queries.on_disk_cache.try_load_query_result(tcx, id).map(Ok)
     }
 }
 
@@ -257,7 +259,7 @@
     fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                               id: SerializedDepNodeIndex)
                               -> Option<Self::Value> {
-        tcx.on_disk_query_result_cache.try_load_query_result(tcx, id)
+        tcx.queries.on_disk_cache.try_load_query_result(tcx, id)
     }
 }
 
@@ -331,7 +333,7 @@
     fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                           id: SerializedDepNodeIndex)
                           -> Option<Self::Value> {
-        tcx.on_disk_query_result_cache.try_load_query_result(tcx, id)
+        tcx.queries.on_disk_cache.try_load_query_result(tcx, id)
     }
 }
 
@@ -363,7 +365,7 @@
     fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                               id: SerializedDepNodeIndex)
                               -> Option<Self::Value> {
-        tcx.on_disk_query_result_cache.try_load_query_result(tcx, id)
+        tcx.queries.on_disk_cache.try_load_query_result(tcx, id)
     }
 }
 
@@ -683,7 +685,7 @@
                           id: SerializedDepNodeIndex)
                           -> Option<Self::Value> {
         let typeck_tables: Option<ty::TypeckTables<'tcx>> = tcx
-            .on_disk_query_result_cache
+            .queries.on_disk_cache
             .try_load_query_result(tcx, id);
 
         typeck_tables.map(|tables| tcx.alloc_tables(tables))
@@ -699,7 +701,7 @@
     fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                               id: SerializedDepNodeIndex)
                               -> Option<Self::Value> {
-        let mir: Option<::mir::Mir<'tcx>> = tcx.on_disk_query_result_cache
+        let mir: Option<::mir::Mir<'tcx>> = tcx.queries.on_disk_cache
                                                .try_load_query_result(tcx, id);
         mir.map(|x| tcx.alloc_mir(x))
     }
@@ -738,7 +740,7 @@
     fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                               id: SerializedDepNodeIndex)
                               -> Option<Self::Value> {
-        let generics: Option<ty::Generics> = tcx.on_disk_query_result_cache
+        let generics: Option<ty::Generics> = tcx.queries.on_disk_cache
                                                 .try_load_query_result(tcx, id);
         generics.map(|x| tcx.alloc_generics(x))
     }
@@ -780,7 +782,7 @@
             fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                       id: SerializedDepNodeIndex)
                                       -> Option<Self::Value> {
-                tcx.on_disk_query_result_cache.try_load_query_result(tcx, id)
+                tcx.queries.on_disk_cache.try_load_query_result(tcx, id)
             }
         }
     }
diff --git a/src/librustc/ty/query/job.rs b/src/librustc/ty/query/job.rs
new file mode 100644
index 0000000..a54deec
--- /dev/null
+++ b/src/librustc/ty/query/job.rs
@@ -0,0 +1,525 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(warnings)]
+
+use std::mem;
+use rustc_data_structures::sync::{Lock, LockGuard, Lrc, Weak};
+use rustc_data_structures::OnDrop;
+use syntax_pos::Span;
+use ty::tls;
+use ty::query::Query;
+use ty::query::plumbing::CycleError;
+use ty::context::TyCtxt;
+use errors::Diagnostic;
+use std::process;
+use std::fmt;
+use std::collections::HashSet;
+#[cfg(parallel_queries)]
+use {
+    rayon_core,
+    parking_lot::{Mutex, Condvar},
+    std::sync::atomic::Ordering,
+    std::thread,
+    std::iter,
+    std::iter::FromIterator,
+    syntax_pos::DUMMY_SP,
+    rustc_data_structures::stable_hasher::{StableHasherResult, StableHasher, HashStable},
+};
+
+/// Indicates the state of a query for a given key in a query map
+pub(super) enum QueryResult<'tcx> {
+    /// An already executing query. The query job can be used to await for its completion
+    Started(Lrc<QueryJob<'tcx>>),
+
+    /// The query panicked. Queries trying to wait on this will raise a fatal error / silently panic
+    Poisoned,
+}
+
+/// A span and a query key
+#[derive(Clone, Debug)]
+pub struct QueryInfo<'tcx> {
+    /// The span for a reason this query was required
+    pub span: Span,
+    pub query: Query<'tcx>,
+}
+
+/// A object representing an active query job.
+pub struct QueryJob<'tcx> {
+    pub info: QueryInfo<'tcx>,
+
+    /// The parent query job which created this job and is implicitly waiting on it.
+    pub parent: Option<Lrc<QueryJob<'tcx>>>,
+
+    /// Diagnostic messages which are emitted while the query executes
+    pub diagnostics: Lock<Vec<Diagnostic>>,
+
+    /// The latch which is used to wait on this job
+    #[cfg(parallel_queries)]
+    latch: QueryLatch<'tcx>,
+}
+
+impl<'tcx> QueryJob<'tcx> {
+    /// Creates a new query job
+    pub fn new(info: QueryInfo<'tcx>, parent: Option<Lrc<QueryJob<'tcx>>>) -> Self {
+        QueryJob {
+            diagnostics: Lock::new(Vec::new()),
+            info,
+            parent,
+            #[cfg(parallel_queries)]
+            latch: QueryLatch::new(),
+        }
+    }
+
+    /// Awaits for the query job to complete.
+    ///
+    /// For single threaded rustc there's no concurrent jobs running, so if we are waiting for any
+    /// query that means that there is a query cycle, thus this always running a cycle error.
+    pub(super) fn await<'lcx>(
+        &self,
+        tcx: TyCtxt<'_, 'tcx, 'lcx>,
+        span: Span,
+    ) -> Result<(), CycleError<'tcx>> {
+        #[cfg(not(parallel_queries))]
+        {
+            self.find_cycle_in_stack(tcx, span)
+        }
+
+        #[cfg(parallel_queries)]
+        {
+            tls::with_related_context(tcx, move |icx| {
+                let mut waiter = Lrc::new(QueryWaiter {
+                    query: icx.query.clone(),
+                    span,
+                    cycle: Lock::new(None),
+                    condvar: Condvar::new(),
+                });
+                self.latch.await(&waiter);
+
+                match Lrc::get_mut(&mut waiter).unwrap().cycle.get_mut().take() {
+                    None => Ok(()),
+                    Some(cycle) => Err(cycle)
+                }
+            })
+        }
+    }
+
+    #[cfg(not(parallel_queries))]
+    fn find_cycle_in_stack<'lcx>(
+        &self,
+        tcx: TyCtxt<'_, 'tcx, 'lcx>,
+        span: Span,
+    ) -> Result<(), CycleError<'tcx>> {
+        // Get the current executing query (waiter) and find the waitee amongst its parents
+        let mut current_job = tls::with_related_context(tcx, |icx| icx.query.clone());
+        let mut cycle = Vec::new();
+
+        while let Some(job) = current_job {
+            cycle.insert(0, job.info.clone());
+
+            if &*job as *const _ == self as *const _ {
+                // This is the end of the cycle
+                // The span entry we included was for the usage
+                // of the cycle itself, and not part of the cycle
+                // Replace it with the span which caused the cycle to form
+                cycle[0].span = span;
+                // Find out why the cycle itself was used
+                let usage = job.parent.as_ref().map(|parent| {
+                    (job.info.span, parent.info.query.clone())
+                });
+                return Err(CycleError { usage, cycle });
+            }
+
+            current_job = job.parent.clone();
+        }
+
+        panic!("did not find a cycle")
+    }
+
+    /// Signals to waiters that the query is complete.
+    ///
+    /// This does nothing for single threaded rustc,
+    /// as there are no concurrent jobs which could be waiting on us
+    pub fn signal_complete(&self) {
+        #[cfg(parallel_queries)]
+        self.latch.set();
+    }
+
+    fn as_ptr(&self) -> *const QueryJob<'tcx> {
+        self as *const _
+    }
+}
+
+#[cfg(parallel_queries)]
+struct QueryWaiter<'tcx> {
+    query: Option<Lrc<QueryJob<'tcx>>>,
+    condvar: Condvar,
+    span: Span,
+    cycle: Lock<Option<CycleError<'tcx>>>,
+}
+
+#[cfg(parallel_queries)]
+impl<'tcx> QueryWaiter<'tcx> {
+    fn notify(&self, registry: &rayon_core::Registry) {
+        rayon_core::mark_unblocked(registry);
+        self.condvar.notify_one();
+    }
+}
+
+#[cfg(parallel_queries)]
+struct QueryLatchInfo<'tcx> {
+    complete: bool,
+    waiters: Vec<Lrc<QueryWaiter<'tcx>>>,
+}
+
+#[cfg(parallel_queries)]
+struct QueryLatch<'tcx> {
+    info: Mutex<QueryLatchInfo<'tcx>>,
+}
+
+#[cfg(parallel_queries)]
+impl<'tcx> QueryLatch<'tcx> {
+    fn new() -> Self {
+        QueryLatch {
+            info: Mutex::new(QueryLatchInfo {
+                complete: false,
+                waiters: Vec::new(),
+            }),
+        }
+    }
+
+    /// Awaits the caller on this latch by blocking the current thread.
+    fn await(&self, waiter: &Lrc<QueryWaiter<'tcx>>) {
+        let mut info = self.info.lock();
+        if !info.complete {
+            // We push the waiter on to the `waiters` list. It can be accessed inside
+            // the `wait` call below, by 1) the `set` method or 2) by deadlock detection.
+            // Both of these will remove it from the `waiters` list before resuming
+            // this thread.
+            info.waiters.push(waiter.clone());
+
+            // If this detects a deadlock and the deadlock handler wants to resume this thread
+            // we have to be in the `wait` call. This is ensured by the deadlock handler
+            // getting the self.info lock.
+            rayon_core::mark_blocked();
+            waiter.condvar.wait(&mut info);
+        }
+    }
+
+    /// Sets the latch and resumes all waiters on it
+    fn set(&self) {
+        let mut info = self.info.lock();
+        debug_assert!(!info.complete);
+        info.complete = true;
+        let registry = rayon_core::Registry::current();
+        for waiter in info.waiters.drain(..) {
+            waiter.notify(&registry);
+        }
+    }
+
+    /// Remove a single waiter from the list of waiters.
+    /// This is used to break query cycles.
+    fn extract_waiter(
+        &self,
+        waiter: usize,
+    ) -> Lrc<QueryWaiter<'tcx>> {
+        let mut info = self.info.lock();
+        debug_assert!(!info.complete);
+        // Remove the waiter from the list of waiters
+        info.waiters.remove(waiter)
+    }
+}
+
+/// A resumable waiter of a query. The usize is the index into waiters in the query's latch
+#[cfg(parallel_queries)]
+type Waiter<'tcx> = (Lrc<QueryJob<'tcx>>, usize);
+
+/// Visits all the non-resumable and resumable waiters of a query.
+/// Only waiters in a query are visited.
+/// `visit` is called for every waiter and is passed a query waiting on `query_ref`
+/// and a span indicating the reason the query waited on `query_ref`.
+/// If `visit` returns Some, this function returns.
+/// For visits of non-resumable waiters it returns the return value of `visit`.
+/// For visits of resumable waiters it returns Some(Some(Waiter)) which has the
+/// required information to resume the waiter.
+/// If all `visit` calls returns None, this function also returns None.
+#[cfg(parallel_queries)]
+fn visit_waiters<'tcx, F>(query: Lrc<QueryJob<'tcx>>, mut visit: F) -> Option<Option<Waiter<'tcx>>>
+where
+    F: FnMut(Span, Lrc<QueryJob<'tcx>>) -> Option<Option<Waiter<'tcx>>>
+{
+    // Visit the parent query which is a non-resumable waiter since it's on the same stack
+    if let Some(ref parent) = query.parent {
+        if let Some(cycle) = visit(query.info.span, parent.clone()) {
+            return Some(cycle);
+        }
+    }
+
+    // Visit the explict waiters which use condvars and are resumable
+    for (i, waiter) in query.latch.info.lock().waiters.iter().enumerate() {
+        if let Some(ref waiter_query) = waiter.query {
+            if visit(waiter.span, waiter_query.clone()).is_some() {
+                // Return a value which indicates that this waiter can be resumed
+                return Some(Some((query.clone(), i)));
+            }
+        }
+    }
+    None
+}
+
+/// Look for query cycles by doing a depth first search starting at `query`.
+/// `span` is the reason for the `query` to execute. This is initially DUMMY_SP.
+/// If a cycle is detected, this initial value is replaced with the span causing
+/// the cycle.
+#[cfg(parallel_queries)]
+fn cycle_check<'tcx>(query: Lrc<QueryJob<'tcx>>,
+                     span: Span,
+                     stack: &mut Vec<(Span, Lrc<QueryJob<'tcx>>)>,
+                     visited: &mut HashSet<*const QueryJob<'tcx>>
+) -> Option<Option<Waiter<'tcx>>> {
+    if visited.contains(&query.as_ptr()) {
+        return if let Some(p) = stack.iter().position(|q| q.1.as_ptr() == query.as_ptr()) {
+            // We detected a query cycle, fix up the initial span and return Some
+
+            // Remove previous stack entries
+            stack.splice(0..p, iter::empty());
+            // Replace the span for the first query with the cycle cause
+            stack[0].0 = span;
+            Some(None)
+        } else {
+            None
+        }
+    }
+
+    // Mark this query is visited and add it to the stack
+    visited.insert(query.as_ptr());
+    stack.push((span, query.clone()));
+
+    // Visit all the waiters
+    let r = visit_waiters(query, |span, successor| {
+        cycle_check(successor, span, stack, visited)
+    });
+
+    // Remove the entry in our stack if we didn't find a cycle
+    if r.is_none() {
+        stack.pop();
+    }
+
+    r
+}
+
+/// Finds out if there's a path to the compiler root (aka. code which isn't in a query)
+/// from `query` without going through any of the queries in `visited`.
+/// This is achieved with a depth first search.
+#[cfg(parallel_queries)]
+fn connected_to_root<'tcx>(
+    query: Lrc<QueryJob<'tcx>>,
+    visited: &mut HashSet<*const QueryJob<'tcx>>
+) -> bool {
+    // We already visited this or we're deliberately ignoring it
+    if visited.contains(&query.as_ptr()) {
+        return false;
+    }
+
+    // This query is connected to the root (it has no query parent), return true
+    if query.parent.is_none() {
+        return true;
+    }
+
+    visited.insert(query.as_ptr());
+
+    let mut connected = false;
+
+    visit_waiters(query, |_, successor| {
+        if connected_to_root(successor, visited) {
+            Some(None)
+        } else {
+            None
+        }
+    }).is_some()
+}
+
+/// Looks for query cycles starting from the last query in `jobs`.
+/// If a cycle is found, all queries in the cycle is removed from `jobs` and
+/// the function return true.
+/// If a cycle was not found, the starting query is removed from `jobs` and
+/// the function returns false.
+#[cfg(parallel_queries)]
+fn remove_cycle<'tcx>(
+    jobs: &mut Vec<Lrc<QueryJob<'tcx>>>,
+    wakelist: &mut Vec<Lrc<QueryWaiter<'tcx>>>,
+    tcx: TyCtxt<'_, 'tcx, '_>
+) -> bool {
+    let mut visited = HashSet::new();
+    let mut stack = Vec::new();
+    // Look for a cycle starting with the last query in `jobs`
+    if let Some(waiter) = cycle_check(jobs.pop().unwrap(),
+                                      DUMMY_SP,
+                                      &mut stack,
+                                      &mut visited) {
+        // Reverse the stack so earlier entries require later entries
+        stack.reverse();
+
+        // Extract the spans and queries into separate arrays
+        let mut spans: Vec<_> = stack.iter().map(|e| e.0).collect();
+        let queries = stack.into_iter().map(|e| e.1);
+
+        // Shift the spans so that queries are matched with the span for their waitee
+        let last = spans.pop().unwrap();
+        spans.insert(0, last);
+
+        // Zip them back together
+        let mut stack: Vec<_> = spans.into_iter().zip(queries).collect();
+
+        // Remove the queries in our cycle from the list of jobs to look at
+        for r in &stack {
+            if let Some(pos) = jobs.iter().position(|j| j.as_ptr() == r.1.as_ptr()) {
+                jobs.remove(pos);
+            }
+        }
+
+        // Find the queries in the cycle which are
+        // connected to queries outside the cycle
+        let entry_points: Vec<Lrc<QueryJob<'tcx>>> = stack.iter().filter_map(|query| {
+            // Mark all the other queries in the cycle as already visited
+            let mut visited = HashSet::from_iter(stack.iter().filter_map(|q| {
+                if q.1.as_ptr() != query.1.as_ptr() {
+                    Some(q.1.as_ptr())
+                } else {
+                    None
+                }
+            }));
+
+            if connected_to_root(query.1.clone(), &mut visited) {
+                Some(query.1.clone())
+            } else {
+                None
+            }
+        }).collect();
+
+        // Deterministically pick an entry point
+        // FIXME: Sort this instead
+        let mut hcx = tcx.create_stable_hashing_context();
+        let entry_point = entry_points.iter().min_by_key(|q| {
+            let mut stable_hasher = StableHasher::<u64>::new();
+            q.info.query.hash_stable(&mut hcx, &mut stable_hasher);
+            stable_hasher.finish()
+        }).unwrap().as_ptr();
+
+        // Shift the stack until our entry point is first
+        while stack[0].1.as_ptr() != entry_point {
+            let last = stack.pop().unwrap();
+            stack.insert(0, last);
+        }
+
+        // Create the cycle error
+        let mut error = CycleError {
+            usage: None,
+            cycle: stack.iter().map(|&(s, ref q)| QueryInfo {
+                span: s,
+                query: q.info.query.clone(),
+            } ).collect(),
+        };
+
+        // We unwrap `waiter` here since there must always be one
+        // edge which is resumeable / waited using a query latch
+        let (waitee_query, waiter_idx) = waiter.unwrap();
+
+        // Extract the waiter we want to resume
+        let waiter = waitee_query.latch.extract_waiter(waiter_idx);
+
+        // Set the cycle error so it will be picked up when resumed
+        *waiter.cycle.lock() = Some(error);
+
+        // Put the waiter on the list of things to resume
+        wakelist.push(waiter);
+
+        true
+    } else {
+        false
+    }
+}
+
+/// Creates a new thread and forwards information in thread locals to it.
+/// The new thread runs the deadlock handler.
+/// Must only be called when a deadlock is about to happen.
+#[cfg(parallel_queries)]
+pub unsafe fn handle_deadlock() {
+    use syntax;
+    use syntax_pos;
+
+    let registry = rayon_core::Registry::current();
+
+    let gcx_ptr = tls::GCX_PTR.with(|gcx_ptr| {
+        gcx_ptr as *const _
+    });
+    let gcx_ptr = &*gcx_ptr;
+
+    let syntax_globals = syntax::GLOBALS.with(|syntax_globals| {
+        syntax_globals as *const _
+    });
+    let syntax_globals = &*syntax_globals;
+
+    let syntax_pos_globals = syntax_pos::GLOBALS.with(|syntax_pos_globals| {
+        syntax_pos_globals as *const _
+    });
+    let syntax_pos_globals = &*syntax_pos_globals;
+    thread::spawn(move || {
+        tls::GCX_PTR.set(gcx_ptr, || {
+            syntax_pos::GLOBALS.set(syntax_pos_globals, || {
+                syntax_pos::GLOBALS.set(syntax_pos_globals, || {
+                    tls::with_thread_locals(|| {
+                        tls::with_global(|tcx| deadlock(tcx, &registry))
+                    })
+                })
+            })
+        })
+    });
+}
+
+/// Detects query cycles by using depth first search over all active query jobs.
+/// If a query cycle is found it will break the cycle by finding an edge which
+/// uses a query latch and then resuming that waiter.
+/// There may be multiple cycles involved in a deadlock, so this searches
+/// all active queries for cycles before finally resuming all the waiters at once.
+#[cfg(parallel_queries)]
+fn deadlock(tcx: TyCtxt<'_, '_, '_>, registry: &rayon_core::Registry) {
+    let on_panic = OnDrop(|| {
+        eprintln!("deadlock handler panicked, aborting process");
+        process::abort();
+    });
+
+    let mut wakelist = Vec::new();
+    let mut jobs: Vec<_> = tcx.queries.collect_active_jobs();
+
+    let mut found_cycle = false;
+
+    while jobs.len() > 0 {
+        if remove_cycle(&mut jobs, &mut wakelist, tcx) {
+            found_cycle = true;
+        }
+    }
+
+    // Check that a cycle was found. It is possible for a deadlock to occur without
+    // a query cycle if a query which can be waited on uses Rayon to do multithreading
+    // internally. Such a query (X) may be executing on 2 threads (A and B) and A may
+    // wait using Rayon on B. Rayon may then switch to executing another query (Y)
+    // which in turn will wait on X causing a deadlock. We have a false dependency from
+    // X to Y due to Rayon waiting and a true dependency from Y to X. The algorithm here
+    // only considers the true dependency and won't detect a cycle.
+    assert!(found_cycle);
+
+    // FIXME: Ensure this won't cause a deadlock before we return
+    for waiter in wakelist.into_iter() {
+        waiter.notify(registry);
+    }
+
+    on_panic.disable();
+}
diff --git a/src/librustc/ty/maps/keys.rs b/src/librustc/ty/query/keys.rs
similarity index 81%
rename from src/librustc/ty/maps/keys.rs
rename to src/librustc/ty/query/keys.rs
index 3510a1b..279d5eb 100644
--- a/src/librustc/ty/maps/keys.rs
+++ b/src/librustc/ty/query/keys.rs
@@ -24,10 +24,10 @@
 
 /// The `Key` trait controls what types can legally be used as the key
 /// for a query.
-pub trait Key: Clone + Hash + Eq + Debug {
+pub(super) trait Key: Clone + Hash + Eq + Debug {
     /// Given an instance of this key, what crate is it referring to?
     /// This is used to find the provider.
-    fn map_crate(&self) -> CrateNum;
+    fn query_crate(&self) -> CrateNum;
 
     /// In the event that a cycle occurs, if no explicit span has been
     /// given for a query with key `self`, what span should we use?
@@ -35,7 +35,7 @@
 }
 
 impl<'tcx> Key for ty::InstanceDef<'tcx> {
-    fn map_crate(&self) -> CrateNum {
+    fn query_crate(&self) -> CrateNum {
         LOCAL_CRATE
     }
 
@@ -45,7 +45,7 @@
 }
 
 impl<'tcx> Key for ty::Instance<'tcx> {
-    fn map_crate(&self) -> CrateNum {
+    fn query_crate(&self) -> CrateNum {
         LOCAL_CRATE
     }
 
@@ -55,8 +55,8 @@
 }
 
 impl<'tcx> Key for mir::interpret::GlobalId<'tcx> {
-    fn map_crate(&self) -> CrateNum {
-        self.instance.map_crate()
+    fn query_crate(&self) -> CrateNum {
+        self.instance.query_crate()
     }
 
     fn default_span(&self, tcx: TyCtxt) -> Span {
@@ -65,7 +65,7 @@
 }
 
 impl Key for CrateNum {
-    fn map_crate(&self) -> CrateNum {
+    fn query_crate(&self) -> CrateNum {
         *self
     }
     fn default_span(&self, _: TyCtxt) -> Span {
@@ -74,7 +74,7 @@
 }
 
 impl Key for DefIndex {
-    fn map_crate(&self) -> CrateNum {
+    fn query_crate(&self) -> CrateNum {
         LOCAL_CRATE
     }
     fn default_span(&self, _tcx: TyCtxt) -> Span {
@@ -83,7 +83,7 @@
 }
 
 impl Key for DefId {
-    fn map_crate(&self) -> CrateNum {
+    fn query_crate(&self) -> CrateNum {
         self.krate
     }
     fn default_span(&self, tcx: TyCtxt) -> Span {
@@ -92,7 +92,7 @@
 }
 
 impl Key for (DefId, DefId) {
-    fn map_crate(&self) -> CrateNum {
+    fn query_crate(&self) -> CrateNum {
         self.0.krate
     }
     fn default_span(&self, tcx: TyCtxt) -> Span {
@@ -101,7 +101,7 @@
 }
 
 impl Key for (CrateNum, DefId) {
-    fn map_crate(&self) -> CrateNum {
+    fn query_crate(&self) -> CrateNum {
         self.0
     }
     fn default_span(&self, tcx: TyCtxt) -> Span {
@@ -110,7 +110,7 @@
 }
 
 impl Key for (DefId, SimplifiedType) {
-    fn map_crate(&self) -> CrateNum {
+    fn query_crate(&self) -> CrateNum {
         self.0.krate
     }
     fn default_span(&self, tcx: TyCtxt) -> Span {
@@ -119,7 +119,7 @@
 }
 
 impl<'tcx> Key for (DefId, &'tcx Substs<'tcx>) {
-    fn map_crate(&self) -> CrateNum {
+    fn query_crate(&self) -> CrateNum {
         self.0.krate
     }
     fn default_span(&self, tcx: TyCtxt) -> Span {
@@ -128,7 +128,7 @@
 }
 
 impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) {
-    fn map_crate(&self) -> CrateNum {
+    fn query_crate(&self) -> CrateNum {
         self.1.def_id().krate
     }
     fn default_span(&self, tcx: TyCtxt) -> Span {
@@ -137,7 +137,7 @@
 }
 
 impl<'tcx> Key for ty::PolyTraitRef<'tcx>{
-    fn map_crate(&self) -> CrateNum {
+    fn query_crate(&self) -> CrateNum {
         self.def_id().krate
     }
     fn default_span(&self, tcx: TyCtxt) -> Span {
@@ -146,7 +146,7 @@
 }
 
 impl<'tcx> Key for (mir::interpret::ConstValue<'tcx>, Ty<'tcx>) {
-    fn map_crate(&self) -> CrateNum {
+    fn query_crate(&self) -> CrateNum {
         LOCAL_CRATE
     }
     fn default_span(&self, _: TyCtxt) -> Span {
@@ -155,7 +155,7 @@
 }
 
 impl<'tcx> Key for Ty<'tcx> {
-    fn map_crate(&self) -> CrateNum {
+    fn query_crate(&self) -> CrateNum {
         LOCAL_CRATE
     }
     fn default_span(&self, _: TyCtxt) -> Span {
@@ -164,7 +164,7 @@
 }
 
 impl<'tcx> Key for ty::ParamEnv<'tcx> {
-    fn map_crate(&self) -> CrateNum {
+    fn query_crate(&self) -> CrateNum {
         LOCAL_CRATE
     }
     fn default_span(&self, _: TyCtxt) -> Span {
@@ -173,8 +173,8 @@
 }
 
 impl<'tcx, T: Key> Key for ty::ParamEnvAnd<'tcx, T> {
-    fn map_crate(&self) -> CrateNum {
-        self.value.map_crate()
+    fn query_crate(&self) -> CrateNum {
+        self.value.query_crate()
     }
     fn default_span(&self, tcx: TyCtxt) -> Span {
         self.value.default_span(tcx)
@@ -182,7 +182,7 @@
 }
 
 impl Key for InternedString {
-    fn map_crate(&self) -> CrateNum {
+    fn query_crate(&self) -> CrateNum {
         LOCAL_CRATE
     }
     fn default_span(&self, _tcx: TyCtxt) -> Span {
@@ -191,7 +191,7 @@
 }
 
 impl<'tcx> Key for CanonicalProjectionGoal<'tcx> {
-    fn map_crate(&self) -> CrateNum {
+    fn query_crate(&self) -> CrateNum {
         LOCAL_CRATE
     }
 
@@ -201,7 +201,7 @@
 }
 
 impl<'tcx> Key for CanonicalTyGoal<'tcx> {
-    fn map_crate(&self) -> CrateNum {
+    fn query_crate(&self) -> CrateNum {
         LOCAL_CRATE
     }
 
@@ -211,7 +211,7 @@
 }
 
 impl<'tcx> Key for CanonicalPredicateGoal<'tcx> {
-    fn map_crate(&self) -> CrateNum {
+    fn query_crate(&self) -> CrateNum {
         LOCAL_CRATE
     }
 
diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/query/mod.rs
similarity index 93%
rename from src/librustc/ty/maps/mod.rs
rename to src/librustc/ty/query/mod.rs
index 6556e47..f19bc01 100644
--- a/src/librustc/ty/maps/mod.rs
+++ b/src/librustc/ty/query/mod.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use dep_graph::{DepConstructor, DepNode};
+use errors::DiagnosticBuilder;
 use hir::def_id::{CrateNum, DefId, DefIndex};
 use hir::def::{Def, Export};
 use hir::{self, TraitCandidate, ItemLocalId, CodegenFnAttrs};
@@ -63,36 +64,38 @@
 #[macro_use]
 mod plumbing;
 use self::plumbing::*;
-pub use self::plumbing::force_from_dep_node;
+pub use self::plumbing::{force_from_dep_node, CycleError};
 
 mod job;
 pub use self::job::{QueryJob, QueryInfo};
+#[cfg(parallel_queries)]
+pub use self::job::handle_deadlock;
 
 mod keys;
-pub use self::keys::Key;
+use self::keys::Key;
 
 mod values;
 use self::values::Value;
 
 mod config;
 pub use self::config::QueryConfig;
-use self::config::QueryDescription;
+use self::config::{QueryAccessors, QueryDescription};
 
 mod on_disk_cache;
 pub use self::on_disk_cache::OnDiskCache;
 
-// Each of these maps also corresponds to a method on a
-// `Provider` trait for requesting a value of that type,
-// and a method on `Maps` itself for doing that in a
-// a way that memoizes and does dep-graph tracking,
-// wrapping around the actual chain of providers that
-// the driver creates (using several `rustc_*` crates).
+// Each of these quries corresponds to a function pointer field in the
+// `Providers` struct for requesting a value of that type, and a method
+// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
+// which memoizes and does dep-graph tracking, wrapping around the actual
+// `Providers` that the driver creates (using several `rustc_*` crates).
 //
-// The result of query must implement Clone. They must also implement ty::maps::values::Value
-// which produces an appropriate error value if the query resulted in a query cycle.
-// Queries marked with `fatal_cycle` do not need that implementation
+// The result type of each query must implement `Clone`, and additionally
+// `ty::query::values::Value`, which produces an appropriate placeholder
+// (error) value if the query resulted in a query cycle.
+// Queries marked with `fatal_cycle` do not need the latter implementation,
 // as they will raise an fatal error on query cycles instead.
-define_maps! { <'tcx>
+define_queries! { <'tcx>
     /// Records the type of every item.
     [] fn type_of: TypeOfItem(DefId) -> Ty<'tcx>,
 
@@ -100,7 +103,7 @@
     /// associated generics and predicates.
     [] fn generics_of: GenericsOfItem(DefId) -> &'tcx ty::Generics,
     [] fn predicates_of: PredicatesOfItem(DefId) -> ty::GenericPredicates<'tcx>,
-    [] fn explicit_predicates_of: PredicatesOfItem(DefId) -> ty::GenericPredicates<'tcx>,
+    [] fn explicit_predicates_of: ExplicitPredicatesOfItem(DefId) -> ty::GenericPredicates<'tcx>,
 
     /// Maps from the def-id of a trait to the list of
     /// super-predicates. This is a subset of the full list of
@@ -466,6 +469,32 @@
         -> Lrc<FxHashMap<DefId, String>>,
 }
 
+// `try_get_query` can't be public because it uses the private query
+// implementation traits, so we provide access to it selectively.
+impl<'a, 'tcx, 'lcx> TyCtxt<'a, 'tcx, 'lcx> {
+    pub fn try_adt_sized_constraint(
+        self,
+        span: Span,
+        key: DefId,
+    ) -> Result<&'tcx [Ty<'tcx>], DiagnosticBuilder<'a>> {
+        self.try_get_query::<queries::adt_sized_constraint>(span, key)
+    }
+    pub fn try_needs_drop_raw(
+        self,
+        span: Span,
+        key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
+    ) -> Result<bool, DiagnosticBuilder<'a>> {
+        self.try_get_query::<queries::needs_drop_raw>(span, key)
+    }
+    pub fn try_optimized_mir(
+        self,
+        span: Span,
+        key: DefId,
+    ) -> Result<&'tcx mir::Mir<'tcx>, DiagnosticBuilder<'a>> {
+        self.try_get_query::<queries::optimized_mir>(span, key)
+    }
+}
+
 //////////////////////////////////////////////////////////////////////
 // These functions are little shims used to find the dep-node for a
 // given query when there is not a *direct* mapping:
diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
similarity index 98%
rename from src/librustc/ty/maps/on_disk_cache.rs
rename to src/librustc/ty/query/on_disk_cache.rs
index cd317ff..3285380 100644
--- a/src/librustc/ty/maps/on_disk_cache.rs
+++ b/src/librustc/ty/query/on_disk_cache.rs
@@ -209,7 +209,7 @@
             let mut query_result_index = EncodedQueryResultIndex::new();
 
             time(tcx.sess, "encode query results", || {
-                use ty::maps::queries::*;
+                use ty::query::queries::*;
                 let enc = &mut encoder;
                 let qri = &mut query_result_index;
 
@@ -232,11 +232,11 @@
                 encode_query_results::<specialization_graph_of, _>(tcx, enc, qri)?;
 
                 // const eval is special, it only encodes successfully evaluated constants
-                use ty::maps::QueryConfig;
-                let map = const_eval::query_map(tcx).borrow();
-                assert!(map.active.is_empty());
-                for (key, entry) in map.results.iter() {
-                    use ty::maps::config::QueryDescription;
+                use ty::query::QueryAccessors;
+                let cache = const_eval::query_cache(tcx).borrow();
+                assert!(cache.active.is_empty());
+                for (key, entry) in cache.results.iter() {
+                    use ty::query::config::QueryDescription;
                     if const_eval::cache_on_disk(key.clone()) {
                         if let Ok(ref value) = entry.value {
                             let dep_node = SerializedDepNodeIndex::new(entry.index.index());
@@ -1099,7 +1099,7 @@
 
     time(tcx.sess, desc, || {
 
-    let map = Q::query_map(tcx).borrow();
+    let map = Q::query_cache(tcx).borrow();
     assert!(map.active.is_empty());
     for (key, entry) in map.results.iter() {
         if Q::cache_on_disk(key.clone()) {
diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/query/plumbing.rs
similarity index 91%
rename from src/librustc/ty/maps/plumbing.rs
rename to src/librustc/ty/query/plumbing.rs
index 4a9d44b..4679c26 100644
--- a/src/librustc/ty/maps/plumbing.rs
+++ b/src/librustc/ty/query/plumbing.rs
@@ -19,10 +19,9 @@
 use errors::FatalError;
 use ty::tls;
 use ty::{TyCtxt};
-use ty::maps::Query;
-use ty::maps::config::QueryConfig;
-use ty::maps::config::QueryDescription;
-use ty::maps::job::{QueryJob, QueryResult, QueryInfo};
+use ty::query::Query;
+use ty::query::config::{QueryConfig, QueryDescription};
+use ty::query::job::{QueryJob, QueryResult, QueryInfo};
 use ty::item_path;
 
 use util::common::{profq_msg, ProfileQueriesMsg, QueryMsg};
@@ -35,7 +34,7 @@
 use syntax_pos::Span;
 use syntax::codemap::DUMMY_SP;
 
-pub struct QueryMap<'tcx, D: QueryConfig<'tcx> + ?Sized> {
+pub struct QueryCache<'tcx, D: QueryConfig<'tcx> + ?Sized> {
     pub(super) results: FxHashMap<D::Key, QueryValue<D::Value>>,
     pub(super) active: FxHashMap<D::Key, QueryResult<'tcx>>,
 }
@@ -56,9 +55,9 @@
     }
 }
 
-impl<'tcx, M: QueryConfig<'tcx>> QueryMap<'tcx, M> {
-    pub(super) fn new() -> QueryMap<'tcx, M> {
-        QueryMap {
+impl<'tcx, M: QueryConfig<'tcx>> QueryCache<'tcx, M> {
+    pub(super) fn new() -> QueryCache<'tcx, M> {
+        QueryCache {
             results: FxHashMap(),
             active: FxHashMap(),
         }
@@ -95,7 +94,7 @@
 /// A type representing the responsibility to execute the job in the `job` field.
 /// This will poison the relevant query if dropped.
 pub(super) struct JobOwner<'a, 'tcx: 'a, Q: QueryDescription<'tcx> + 'a> {
-    map: &'a Lock<QueryMap<'tcx, Q>>,
+    cache: &'a Lock<QueryCache<'tcx, Q>>,
     key: Q::Key,
     job: Lrc<QueryJob<'tcx>>,
 }
@@ -114,9 +113,9 @@
         span: Span,
         key: &Q::Key,
     ) -> TryGetJob<'a, 'tcx, Q> {
-        let map = Q::query_map(tcx);
+        let cache = Q::query_cache(tcx);
         loop {
-            let mut lock = map.borrow_mut();
+            let mut lock = cache.borrow_mut();
             if let Some(value) = lock.results.get(key) {
                 profq_msg!(tcx, ProfileQueriesMsg::CacheHit);
                 let result = Ok((value.value.clone(), value.index));
@@ -138,7 +137,7 @@
                         };
                         let job = Lrc::new(QueryJob::new(info, icx.query.clone()));
                         let owner = JobOwner {
-                            map,
+                            cache,
                             job: job.clone(),
                             key: (*key).clone(),
                         };
@@ -155,20 +154,20 @@
         }
     }
 
-    /// Completes the query by updating the query map with the `result`,
+    /// Completes the query by updating the query cache with the `result`,
     /// signals the waiter and forgets the JobOwner, so it won't poison the query
     pub(super) fn complete(self, result: &Q::Value, dep_node_index: DepNodeIndex) {
         // We can move out of `self` here because we `mem::forget` it below
         let key = unsafe { ptr::read(&self.key) };
         let job = unsafe { ptr::read(&self.job) };
-        let map = self.map;
+        let cache = self.cache;
 
         // Forget ourself so our destructor won't poison the query
         mem::forget(self);
 
         let value = QueryValue::new(result.clone(), dep_node_index);
         {
-            let mut lock = map.borrow_mut();
+            let mut lock = cache.borrow_mut();
             lock.active.remove(&key);
             lock.results.insert(key, value);
         }
@@ -215,7 +214,7 @@
 impl<'a, 'tcx, Q: QueryDescription<'tcx>> Drop for JobOwner<'a, 'tcx, Q> {
     fn drop(&mut self) {
         // Poison the query so jobs waiting on it panic
-        self.map.borrow_mut().active.insert(self.key.clone(), QueryResult::Poisoned);
+        self.cache.borrow_mut().active.insert(self.key.clone(), QueryResult::Poisoned);
         // Also signal the completion of the job, so waiters
         // will continue execution
         self.job.signal_complete();
@@ -223,7 +222,7 @@
 }
 
 #[derive(Clone)]
-pub(super) struct CycleError<'tcx> {
+pub struct CycleError<'tcx> {
     /// The query and related span which uses the cycle
     pub(super) usage: Option<(Span, Query<'tcx>)>,
     pub(super) cycle: Vec<QueryInfo<'tcx>>,
@@ -231,7 +230,7 @@
 
 /// The result of `try_get_lock`
 pub(super) enum TryGetJob<'a, 'tcx: 'a, D: QueryDescription<'tcx> + 'a> {
-    /// The query is not yet started. Contains a guard to the map eventually used to start it.
+    /// The query is not yet started. Contains a guard to the cache eventually used to start it.
     NotYetStarted(JobOwner<'a, 'tcx, D>),
 
     /// The query was already completed.
@@ -392,7 +391,7 @@
 
             self.dep_graph.read_index(dep_node_index);
 
-            self.on_disk_query_result_cache
+            self.queries.on_disk_cache
                 .store_diagnostics_for_anon_node(dep_node_index, diagnostics);
 
             job.complete(&result, dep_node_index);
@@ -546,7 +545,7 @@
         }
 
         if dep_node.kind != ::dep_graph::DepKind::Null {
-            self.on_disk_query_result_cache
+            self.queries.on_disk_cache
                 .store_diagnostics(dep_node_index, diagnostics);
         }
 
@@ -562,7 +561,7 @@
     /// side-effects -- e.g., in order to report errors for erroneous programs.
     ///
     /// Note: The optimization is only available during incr. comp.
-    pub fn ensure_query<Q: QueryDescription<'gcx>>(self, key: Q::Key) -> () {
+    pub(super) fn ensure_query<Q: QueryDescription<'gcx>>(self, key: Q::Key) -> () {
         let dep_node = Q::to_dep_node(self, &key);
 
         // Ensuring an "input" or anonymous query makes no sense
@@ -595,10 +594,10 @@
         self.force_query_with_job::<Q>(key, job, dep_node)
     }
 
-    pub fn try_get_query<Q: QueryDescription<'gcx>>(
+    pub(super) fn try_get_query<Q: QueryDescription<'gcx>>(
         self,
         span: Span,
-        key: Q::Key
+        key: Q::Key,
     ) -> Result<Q::Value, DiagnosticBuilder<'a>> {
         match self.try_get_with::<Q>(span, key) {
             Ok(e) => Ok(e),
@@ -606,7 +605,11 @@
         }
     }
 
-    pub fn get_query<Q: QueryDescription<'gcx>>(self, span: Span, key: Q::Key) -> Q::Value {
+    pub(super) fn get_query<Q: QueryDescription<'gcx>>(
+        self,
+        span: Span,
+        key: Q::Key,
+    ) -> Q::Value {
         self.try_get_query::<Q>(span, key).unwrap_or_else(|mut e| {
             e.emit();
             Q::handle_cycle_error(self)
@@ -627,30 +630,58 @@
     };
 }
 
-macro_rules! define_maps {
+macro_rules! define_queries {
     (<$tcx:tt>
      $($(#[$attr:meta])*
        [$($modifiers:tt)*] fn $name:ident: $node:ident($K:ty) -> $V:ty,)*) => {
 
+        use std::mem;
+        #[cfg(parallel_queries)]
+        use ty::query::job::QueryResult;
         use rustc_data_structures::sync::Lock;
+        use {
+            rustc_data_structures::stable_hasher::HashStable,
+            rustc_data_structures::stable_hasher::StableHasherResult,
+            rustc_data_structures::stable_hasher::StableHasher,
+            ich::StableHashingContext
+        };
 
-        define_map_struct! {
+        define_queries_struct! {
             tcx: $tcx,
             input: ($(([$($modifiers)*] [$($attr)*] [$name]))*)
         }
 
-        impl<$tcx> Maps<$tcx> {
-            pub fn new(providers: IndexVec<CrateNum, Providers<$tcx>>)
-                       -> Self {
-                Maps {
+        impl<$tcx> Queries<$tcx> {
+            pub fn new(
+                providers: IndexVec<CrateNum, Providers<$tcx>>,
+                on_disk_cache: OnDiskCache<'tcx>,
+            ) -> Self {
+                Queries {
                     providers,
-                    $($name: Lock::new(QueryMap::new())),*
+                    on_disk_cache,
+                    $($name: Lock::new(QueryCache::new())),*
                 }
             }
+
+            #[cfg(parallel_queries)]
+            pub fn collect_active_jobs(&self) -> Vec<Lrc<QueryJob<$tcx>>> {
+                let mut jobs = Vec::new();
+
+                // We use try_lock here since we are only called from the
+                // deadlock handler, and this shouldn't be locked
+                $(for v in self.$name.try_lock().unwrap().active.values() {
+                    match *v {
+                        QueryResult::Started(ref job) => jobs.push(job.clone()),
+                        _ => (),
+                    }
+                })*
+
+                return jobs;
+            }
         }
 
         #[allow(bad_style)]
-        #[derive(Copy, Clone, Debug, PartialEq, Eq)]
+        #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
         pub enum Query<$tcx> {
             $($(#[$attr])* $name($K)),*
         }
@@ -692,6 +723,17 @@
             }
         }
 
+        impl<'a, $tcx> HashStable<StableHashingContext<'a>> for Query<$tcx> {
+            fn hash_stable<W: StableHasherResult>(&self,
+                                                hcx: &mut StableHashingContext<'a>,
+                                                hasher: &mut StableHasher<W>) {
+                mem::discriminant(self).hash_stable(hcx, hasher);
+                match *self {
+                    $(Query::$name(key) => key.hash_stable(hcx, hasher),)*
+                }
+            }
+        }
+
         pub mod queries {
             use std::marker::PhantomData;
 
@@ -716,13 +758,15 @@
             type Value = $V;
 
             const NAME: &'static str = stringify!($name);
+        }
 
+        impl<$tcx> QueryAccessors<$tcx> for queries::$name<$tcx> {
             fn query(key: Self::Key) -> Query<'tcx> {
                 Query::$name(key)
             }
 
-            fn query_map<'a>(tcx: TyCtxt<'a, $tcx, '_>) -> &'a Lock<QueryMap<$tcx, Self>> {
-                &tcx.maps.$name
+            fn query_cache<'a>(tcx: TyCtxt<'a, $tcx, '_>) -> &'a Lock<QueryCache<$tcx, Self>> {
+                &tcx.queries.$name
             }
 
             #[allow(unused)]
@@ -735,7 +779,7 @@
             #[inline]
             fn compute(tcx: TyCtxt<'_, 'tcx, '_>, key: Self::Key) -> Self::Value {
                 __query_compute::$name(move || {
-                    let provider = tcx.maps.providers[key.map_crate()].$name;
+                    let provider = tcx.queries.providers[key.query_crate()].$name;
                     provider(tcx.global_tcx(), key)
                 })
             }
@@ -806,12 +850,18 @@
     }
 }
 
-macro_rules! define_map_struct {
+macro_rules! define_queries_struct {
     (tcx: $tcx:tt,
      input: ($(([$($modifiers:tt)*] [$($attr:tt)*] [$name:ident]))*)) => {
-        pub struct Maps<$tcx> {
+        pub(crate) struct Queries<$tcx> {
+            /// This provides access to the incr. comp. on-disk cache for query results.
+            /// Do not access this directly. It is only meant to be used by
+            /// `DepGraph::try_mark_green()` and the query infrastructure.
+            pub(crate) on_disk_cache: OnDiskCache<'tcx>,
+
             providers: IndexVec<CrateNum, Providers<$tcx>>,
-            $($(#[$attr])*  $name: Lock<QueryMap<$tcx, queries::$name<$tcx>>>,)*
+
+            $($(#[$attr])*  $name: Lock<QueryCache<$tcx, queries::$name<$tcx>>>,)*
         }
     };
 }
@@ -826,7 +876,7 @@
         impl<$tcx> Default for Providers<$tcx> {
             fn default() -> Self {
                 $(fn $name<'a, $tcx>(_: TyCtxt<'a, $tcx, $tcx>, key: $K) -> $R {
-                    bug!("tcx.maps.{}({:?}) unsupported by its crate",
+                    bug!("tcx.{}({:?}) unsupported by its crate",
                          stringify!($name), key);
                 })*
                 Providers { $($name),* }
@@ -926,11 +976,11 @@
                 profq_msg!(tcx,
                     ProfileQueriesMsg::QueryBegin(
                         DUMMY_SP.data(),
-                        profq_query_msg!(::ty::maps::queries::$query::NAME, tcx, $key),
+                        profq_query_msg!(::ty::query::queries::$query::NAME, tcx, $key),
                     )
                 );
 
-                match tcx.force_query::<::ty::maps::queries::$query>($key, DUMMY_SP, *dep_node) {
+                match tcx.force_query::<::ty::query::queries::$query>($key, DUMMY_SP, *dep_node) {
                     Ok(_) => {},
                     Err(e) => {
                         tcx.report_cycle(e).emit();
@@ -1017,6 +1067,7 @@
         DepKind::TypeOfItem => { force!(type_of, def_id!()); }
         DepKind::GenericsOfItem => { force!(generics_of, def_id!()); }
         DepKind::PredicatesOfItem => { force!(predicates_of, def_id!()); }
+        DepKind::ExplicitPredicatesOfItem => { force!(explicit_predicates_of, def_id!()); }
         DepKind::InferredOutlivesOf => { force!(inferred_outlives_of, def_id!()); }
         DepKind::InferredOutlivesCrate => { force!(inferred_outlives_crate, LOCAL_CRATE); }
         DepKind::SuperPredicatesOfItem => { force!(super_predicates_of, def_id!()); }
@@ -1166,15 +1217,15 @@
 
 
 // FIXME(#45015): Another piece of boilerplate code that could be generated in
-//                a combined define_dep_nodes!()/define_maps!() macro.
+//                a combined define_dep_nodes!()/define_queries!() macro.
 macro_rules! impl_load_from_cache {
     ($($dep_kind:ident => $query_name:ident,)*) => {
         impl DepNode {
             // Check whether the query invocation corresponding to the given
             // DepNode is eligible for on-disk-caching.
             pub fn cache_on_disk(&self, tcx: TyCtxt) -> bool {
-                use ty::maps::queries;
-                use ty::maps::QueryDescription;
+                use ty::query::queries;
+                use ty::query::QueryDescription;
 
                 match self.kind {
                     $(DepKind::$dep_kind => {
diff --git a/src/librustc/ty/maps/values.rs b/src/librustc/ty/query/values.rs
similarity index 100%
rename from src/librustc/ty/maps/values.rs
rename to src/librustc/ty/query/values.rs
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index e77ede7..79a6311 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -476,7 +476,6 @@
     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
         Some(interpret::EvalError {
             kind: tcx.lift(&self.kind)?,
-            backtrace: self.backtrace.clone(),
         })
     }
 }
@@ -578,7 +577,7 @@
             PathNotFound(ref v) => PathNotFound(v.clone()),
             UnimplementedTraitSelection => UnimplementedTraitSelection,
             TypeckError => TypeckError,
-            ReferencedConstant => ReferencedConstant,
+            ReferencedConstant(ref err) => ReferencedConstant(tcx.lift(err)?),
             OverflowNeg => OverflowNeg,
             Overflow(op) => Overflow(op),
             DivisionByZero => DivisionByZero,
@@ -595,14 +594,7 @@
         use middle::const_val::ErrKind::*;
 
         Some(match *self {
-            NonConstPath => NonConstPath,
-            UnimplementedConstVal(s) => UnimplementedConstVal(s),
-            IndexOutOfBounds { len, index } => IndexOutOfBounds { len, index },
-
-            LayoutError(ref e) => {
-                return tcx.lift(e).map(LayoutError)
-            }
-
+            CouldNotResolve => CouldNotResolve,
             TypeckError => TypeckError,
             CheckMatchError => CheckMatchError,
             Miri(ref e, ref frames) => return tcx.lift(e).map(|e| Miri(e, frames.clone())),
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index f484fda..4a69fbd 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -496,7 +496,9 @@
 }
 
 impl<'a, 'gcx, 'tcx> ExistentialPredicate<'tcx> {
-    pub fn cmp(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, other: &Self) -> Ordering {
+    /// Compares via an ordering that will not change if modules are reordered or other changes are
+    /// made to the tree. In particular, this ordering is preserved across incremental compilations.
+    pub fn stable_cmp(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, other: &Self) -> Ordering {
         use self::ExistentialPredicate::*;
         match (*self, *other) {
             (Trait(_), Trait(_)) => Ordering::Equal,
@@ -1021,12 +1023,11 @@
 /// is the outer fn.
 ///
 /// [dbi]: http://en.wikipedia.org/wiki/De_Bruijn_index
-#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug, Copy, PartialOrd, Ord)]
-pub struct DebruijnIndex {
-    /// We maintain the invariant that this is never 0. So 1 indicates
-    /// the innermost binder.
-    index: u32,
-}
+newtype_index!(DebruijnIndex
+    {
+        DEBUG_FORMAT = "DebruijnIndex({})",
+        const INNERMOST = 0,
+    });
 
 pub type Region<'tcx> = &'tcx RegionKind;
 
@@ -1259,8 +1260,6 @@
 }
 
 impl DebruijnIndex {
-    pub const INNERMOST: DebruijnIndex = DebruijnIndex { index: 0 };
-
     /// Returns the resulting index when this value is moved into
     /// `amount` number of new binders. So e.g. if you had
     ///
@@ -1273,7 +1272,7 @@
     /// you would need to shift the index for `'a` into 1 new binder.
     #[must_use]
     pub const fn shifted_in(self, amount: u32) -> DebruijnIndex {
-        DebruijnIndex { index: self.index + amount }
+        DebruijnIndex(self.0 + amount)
     }
 
     /// Update this index in place by shifting it "in" through
@@ -1286,7 +1285,7 @@
     /// `amount` number of new binders.
     #[must_use]
     pub const fn shifted_out(self, amount: u32) -> DebruijnIndex {
-        DebruijnIndex { index: self.index - amount }
+        DebruijnIndex(self.0 - amount)
     }
 
     /// Update in place by shifting out from `amount` binders.
@@ -1315,13 +1314,11 @@
     /// bound by one of the binders we are shifting out of, that is an
     /// error (and should fail an assertion failure).
     pub fn shifted_out_to_binder(self, to_binder: DebruijnIndex) -> Self {
-        self.shifted_out(to_binder.index - Self::INNERMOST.index)
+        self.shifted_out((to_binder.0 - INNERMOST.0) as u32)
     }
 }
 
-impl_stable_hash_for!(struct DebruijnIndex {
-    index
-});
+impl_stable_hash_for!(tuple_struct DebruijnIndex { index });
 
 /// Region utilities
 impl RegionKind {
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 9ef3308..0248854 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -18,7 +18,7 @@
 use traits::{self, ObligationCause};
 use ty::{self, Ty, TyCtxt, GenericParamDefKind, TypeFoldable};
 use ty::subst::{Substs, UnpackedKind};
-use ty::maps::TyCtxtAt;
+use ty::query::TyCtxtAt;
 use ty::TypeVariants::*;
 use ty::layout::{Integer, IntegerExt};
 use util::common::ErrorReported;
@@ -415,7 +415,7 @@
             return None;
         };
 
-        ty::maps::queries::coherent_trait::ensure(self, drop_trait);
+        ty::query::queries::coherent_trait::ensure(self, drop_trait);
 
         let mut dtor_did = None;
         let ty = self.type_of(adt_did);
@@ -555,7 +555,7 @@
                           -> Option<ty::Binder<Ty<'tcx>>>
     {
         let closure_ty = self.mk_closure(closure_def_id, closure_substs);
-        let env_region = ty::ReLateBound(ty::DebruijnIndex::INNERMOST, ty::BrEnv);
+        let env_region = ty::ReLateBound(ty::INNERMOST, ty::BrEnv);
         let closure_kind_ty = closure_substs.closure_kind_ty(closure_def_id, self);
         let closure_kind = closure_kind_ty.to_opt_closure_kind()?;
         let env_ty = match closure_kind {
@@ -883,7 +883,7 @@
     let (param_env, ty) = query.into_parts();
 
     let needs_drop = |ty: Ty<'tcx>| -> bool {
-        match tcx.try_get_query::<ty::queries::needs_drop_raw>(DUMMY_SP, param_env.and(ty)) {
+        match tcx.try_needs_drop_raw(DUMMY_SP, param_env.and(ty)) {
             Ok(v) => v,
             Err(mut bug) => {
                 // Cycles should be reported as an error by `check_representable`.
@@ -1014,8 +1014,8 @@
     }
 }
 
-pub fn provide(providers: &mut ty::maps::Providers) {
-    *providers = ty::maps::Providers {
+pub fn provide(providers: &mut ty::query::Providers) {
+    *providers = ty::query::Providers {
         is_copy_raw,
         is_sized_raw,
         is_freeze_raw,
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 4e7df0c..883882d 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -291,7 +291,8 @@
                     DefPathData::Field(_) |
                     DefPathData::StructCtor |
                     DefPathData::AnonConst |
-                    DefPathData::ImplTrait |
+                    DefPathData::ExistentialImplTrait |
+                    DefPathData::UniversalImplTrait |
                     DefPathData::GlobalMetaData(_) => {
                         // if we're making a symbol for something, there ought
                         // to be a value or type-def or something in there
@@ -526,7 +527,7 @@
                     ty::BrNamed(tcx.hir.local_def_id(CRATE_NODE_ID), name)
                 }
             };
-            tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::INNERMOST, br))
+            tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br))
         }).0;
         start_or_continue(f, "", "> ")?;
 
diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs
index 497d5fd..ec06762 100644
--- a/src/librustc_allocator/expand.rs
+++ b/src/librustc_allocator/expand.rs
@@ -237,7 +237,7 @@
                 let ident = ident();
                 args.push(self.cx.arg(self.span, ident, self.ptr_u8()));
                 let arg = self.cx.expr_ident(self.span, ident);
-                self.cx.expr_cast(self.span, arg, self.ptr_opaque())
+                self.cx.expr_cast(self.span, arg, self.ptr_u8())
             }
 
             AllocatorTy::Usize => {
@@ -281,17 +281,4 @@
         let ty_u8 = self.cx.ty_path(u8);
         self.cx.ty_ptr(self.span, ty_u8, Mutability::Mutable)
     }
-
-    fn ptr_opaque(&self) -> P<Ty> {
-        let opaque = self.cx.path(
-            self.span,
-            vec![
-                self.core,
-                Ident::from_str("alloc"),
-                Ident::from_str("Opaque"),
-            ],
-        );
-        let ty_opaque = self.cx.ty_path(opaque);
-        self.cx.ty_ptr(self.span, ty_opaque, Mutability::Mutable)
-    }
 }
diff --git a/src/librustc_asan/lib.rs b/src/librustc_asan/lib.rs
index 3429e3b..a7aeed7 100644
--- a/src/librustc_asan/lib.rs
+++ b/src/librustc_asan/lib.rs
@@ -10,8 +10,7 @@
 
 #![sanitizer_runtime]
 #![feature(alloc_system)]
-#![feature(allocator_api)]
-#![feature(global_allocator)]
+#![cfg_attr(stage0, feature(global_allocator))]
 #![feature(sanitizer_runtime)]
 #![feature(staged_api)]
 #![no_std]
diff --git a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs
index 18026a1..8493190 100644
--- a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs
+++ b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs
@@ -147,7 +147,7 @@
         }
         Categorization::Interior(ref b, mc::InteriorElement(ik)) => {
             bccx.cannot_move_out_of_interior_noncopy(
-                move_from.span, b.ty, ik == Kind::Index, Origin::Ast)
+                move_from.span, b.ty, Some(ik == Kind::Index), Origin::Ast)
         }
 
         Categorization::Downcast(ref b, _) |
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index 9d0d8c2..11d35de 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -37,7 +37,7 @@
 use rustc::middle::region;
 use rustc::middle::free_region::RegionRelations;
 use rustc::ty::{self, Ty, TyCtxt};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc_mir::util::borrowck_errors::{BorrowckErrors, Origin};
 use rustc::util::nodemap::FxHashSet;
 
@@ -128,7 +128,7 @@
     // Note that `mir_validated` is a "stealable" result; the
     // thief, `optimized_mir()`, forces borrowck, so we know that
     // is not yet stolen.
-    ty::maps::queries::mir_validated::ensure(tcx, owner_def_id);
+    ty::query::queries::mir_validated::ensure(tcx, owner_def_id);
 
     // option dance because you can't capture an uninitialized variable
     // by mut-ref.
@@ -899,7 +899,7 @@
                 };
 
                 self.note_and_explain_mutbl_error(&mut db, &err, &error_span);
-                self.note_immutability_blame(&mut db, err.cmt.immutability_blame());
+                self.note_immutability_blame(&mut db, err.cmt.immutability_blame(), err.cmt.id);
                 db.emit();
             }
             err_out_of_scope(super_scope, sub_scope, cause) => {
@@ -1105,7 +1105,7 @@
                                                             Origin::Ast)
             }
         };
-        self.note_immutability_blame(&mut err, blame);
+        self.note_immutability_blame(&mut err, blame, cmt.id);
 
         if is_closure {
             err.help("closures behind references must be called via `&mut`");
@@ -1184,25 +1184,13 @@
 
     fn note_immutability_blame(&self,
                                db: &mut DiagnosticBuilder,
-                               blame: Option<ImmutabilityBlame>) {
+                               blame: Option<ImmutabilityBlame>,
+                               error_node_id: ast::NodeId) {
         match blame {
             None => {}
             Some(ImmutabilityBlame::ClosureEnv(_)) => {}
             Some(ImmutabilityBlame::ImmLocal(node_id)) => {
-                let let_span = self.tcx.hir.span(node_id);
-                if let ty::BindByValue(..) = self.local_binding_mode(node_id) {
-                    if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(let_span) {
-                        let (_, is_implicit_self) = self.local_ty(node_id);
-                        if is_implicit_self && snippet != "self" {
-                            // avoid suggesting `mut &self`.
-                            return
-                        }
-                        db.span_label(
-                            let_span,
-                            format!("consider changing this to `mut {}`", snippet)
-                        );
-                    }
-                }
+                self.note_immutable_local(db, error_node_id, node_id)
             }
             Some(ImmutabilityBlame::LocalDeref(node_id)) => {
                 let let_span = self.tcx.hir.span(node_id);
@@ -1242,6 +1230,46 @@
         }
     }
 
+     // Suggest a fix when trying to mutably borrow an immutable local
+     // binding: either to make the binding mutable (if its type is
+     // not a mutable reference) or to avoid borrowing altogether
+    fn note_immutable_local(&self,
+                            db: &mut DiagnosticBuilder,
+                            borrowed_node_id: ast::NodeId,
+                            binding_node_id: ast::NodeId) {
+        let let_span = self.tcx.hir.span(binding_node_id);
+        if let ty::BindByValue(..) = self.local_binding_mode(binding_node_id) {
+            if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(let_span) {
+                let (ty, is_implicit_self) = self.local_ty(binding_node_id);
+                if is_implicit_self && snippet != "self" {
+                    // avoid suggesting `mut &self`.
+                    return
+                }
+                if let Some(&hir::TyRptr(
+                    _,
+                    hir::MutTy {
+                        mutbl: hir::MutMutable,
+                        ..
+                    },
+                )) = ty.map(|t| &t.node)
+                {
+                    let borrow_expr_id = self.tcx.hir.get_parent_node(borrowed_node_id);
+                    db.span_suggestion(
+                        self.tcx.hir.span(borrow_expr_id),
+                        "consider removing the `&mut`, as it is an \
+                        immutable binding to a mutable reference",
+                        snippet
+                    );
+                } else {
+                    db.span_label(
+                        let_span,
+                        format!("consider changing this to `mut {}`", snippet),
+                    );
+                }
+            }
+        }
+    }
+
     fn report_out_of_scope_escaping_closure_capture(&self,
                                                     err: &BckError<'a, 'tcx>,
                                                     capture_span: Span)
diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs
index d6806e7..a5d04c5 100644
--- a/src/librustc_codegen_llvm/attributes.rs
+++ b/src/librustc_codegen_llvm/attributes.rs
@@ -17,7 +17,7 @@
 use rustc::session::Session;
 use rustc::session::config::Sanitizer;
 use rustc::ty::TyCtxt;
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_target::spec::PanicStrategy;
diff --git a/src/librustc_codegen_llvm/back/link.rs b/src/librustc_codegen_llvm/back/link.rs
index 735c4d2..4e9910e 100644
--- a/src/librustc_codegen_llvm/back/link.rs
+++ b/src/librustc_codegen_llvm/back/link.rs
@@ -625,6 +625,11 @@
     if let Some(args) = sess.target.target.options.pre_link_args.get(&flavor) {
         cmd.args(args);
     }
+    if let Some(args) = sess.target.target.options.pre_link_args_crt.get(&flavor) {
+        if sess.crt_static() {
+            cmd.args(args);
+        }
+    }
     if let Some(ref args) = sess.opts.debugging_opts.pre_link_args {
         cmd.args(args);
     }
@@ -639,6 +644,12 @@
         cmd.arg(root.join(obj));
     }
 
+    if crate_type == config::CrateTypeExecutable && sess.crt_static() {
+        for obj in &sess.target.target.options.pre_link_objects_exe_crt {
+            cmd.arg(root.join(obj));
+        }
+    }
+
     if sess.target.target.options.is_like_emscripten {
         cmd.arg("-s");
         cmd.arg(if sess.panic_strategy() == PanicStrategy::Abort {
@@ -660,6 +671,11 @@
     for obj in &sess.target.target.options.post_link_objects {
         cmd.arg(root.join(obj));
     }
+    if sess.crt_static() {
+        for obj in &sess.target.target.options.post_link_objects_crt {
+            cmd.arg(root.join(obj));
+        }
+    }
     if let Some(args) = sess.target.target.options.post_link_args.get(&flavor) {
         cmd.args(args);
     }
diff --git a/src/librustc_codegen_llvm/back/symbol_export.rs b/src/librustc_codegen_llvm/back/symbol_export.rs
index 81ac684..28e76a8 100644
--- a/src/librustc_codegen_llvm/back/symbol_export.rs
+++ b/src/librustc_codegen_llvm/back/symbol_export.rs
@@ -19,7 +19,7 @@
 use rustc::middle::exported_symbols::{SymbolExportLevel, ExportedSymbol, metadata_symbol_name};
 use rustc::session::config;
 use rustc::ty::{TyCtxt, SymbolName};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::ty::subst::Substs;
 use rustc::util::nodemap::{FxHashMap, DefIdMap};
 use rustc_allocator::ALLOCATOR_METHODS;
diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs
index 8660c0b..3229245 100644
--- a/src/librustc_codegen_llvm/base.rs
+++ b/src/librustc_codegen_llvm/base.rs
@@ -41,7 +41,7 @@
 use rustc::middle::cstore::{EncodedMetadata};
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::layout::{self, Align, TyLayout, LayoutOf};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::dep_graph::{DepNode, DepConstructor};
 use rustc::middle::cstore::{self, LinkMeta, LinkagePreference};
 use rustc::middle::exported_symbols;
diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs
index ab99d1f..7e55642 100644
--- a/src/librustc_codegen_llvm/common.rs
+++ b/src/librustc_codegen_llvm/common.rs
@@ -425,7 +425,7 @@
             let tcx = cx.tcx;
             let sig = substs.poly_sig(def_id, cx.tcx);
 
-            let env_region = ty::ReLateBound(ty::DebruijnIndex::INNERMOST, ty::BrEnv);
+            let env_region = ty::ReLateBound(ty::INNERMOST, ty::BrEnv);
             let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty);
 
             sig.map_bound(|sig| {
diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs
index 0b0bab9..8732e11 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/src/librustc_codegen_llvm/lib.rs
@@ -183,14 +183,14 @@
         box metadata::LlvmMetadataLoader
     }
 
-    fn provide(&self, providers: &mut ty::maps::Providers) {
+    fn provide(&self, providers: &mut ty::query::Providers) {
         back::symbol_names::provide(providers);
         back::symbol_export::provide(providers);
         base::provide(providers);
         attributes::provide(providers);
     }
 
-    fn provide_extern(&self, providers: &mut ty::maps::Providers) {
+    fn provide_extern(&self, providers: &mut ty::query::Providers) {
         back::symbol_export::provide_extern(providers);
         base::provide_extern(providers);
         attributes::provide_extern(providers);
diff --git a/src/librustc_codegen_llvm/mir/block.rs b/src/librustc_codegen_llvm/mir/block.rs
index 1669059..14d20b6 100644
--- a/src/librustc_codegen_llvm/mir/block.rs
+++ b/src/librustc_codegen_llvm/mir/block.rs
@@ -191,14 +191,23 @@
 
             mir::TerminatorKind::SwitchInt { ref discr, switch_ty, ref values, ref targets } => {
                 let discr = self.codegen_operand(&bx, discr);
-                if switch_ty == bx.tcx().types.bool {
+                if targets.len() == 2 {
+                    // If there are two targets, emit br instead of switch
                     let lltrue = llblock(self, targets[0]);
                     let llfalse = llblock(self, targets[1]);
-                    if let [0] = values[..] {
-                        bx.cond_br(discr.immediate(), llfalse, lltrue);
+                    if switch_ty == bx.tcx().types.bool {
+                        // Don't generate trivial icmps when switching on bool
+                        if let [0] = values[..] {
+                            bx.cond_br(discr.immediate(), llfalse, lltrue);
+                        } else {
+                            assert_eq!(&values[..], &[1]);
+                            bx.cond_br(discr.immediate(), lltrue, llfalse);
+                        }
                     } else {
-                        assert_eq!(&values[..], &[1]);
-                        bx.cond_br(discr.immediate(), lltrue, llfalse);
+                        let switch_llty = bx.cx.layout_of(switch_ty).immediate_llvm_type(bx.cx);
+                        let llval = C_uint_big(switch_llty, values[0]);
+                        let cmp = bx.icmp(llvm::IntEQ, discr.immediate(), llval);
+                        bx.cond_br(cmp, lltrue, llfalse);
                     }
                 } else {
                     let (otherwise, targets) = targets.split_last().unwrap();
diff --git a/src/librustc_codegen_llvm/mir/constant.rs b/src/librustc_codegen_llvm/mir/constant.rs
index ef0bc3e..7c1035e 100644
--- a/src/librustc_codegen_llvm/mir/constant.rs
+++ b/src/librustc_codegen_llvm/mir/constant.rs
@@ -217,7 +217,10 @@
                 Ok((llval, constant.ty))
             })
             .unwrap_or_else(|e| {
-                e.report(bx.tcx(), constant.span, "shuffle_indices");
+                e.report_as_error(
+                    bx.tcx().at(constant.span),
+                    "could not evaluate shuffle_indices at compile time",
+                );
                 // We've errored, so we don't have to produce working code.
                 let ty = self.monomorphize(&constant.ty);
                 let llty = bx.cx.layout_of(ty).llvm_type(bx.cx);
diff --git a/src/librustc_codegen_llvm/mir/operand.rs b/src/librustc_codegen_llvm/mir/operand.rs
index 98383e8..9f32b41 100644
--- a/src/librustc_codegen_llvm/mir/operand.rs
+++ b/src/librustc_codegen_llvm/mir/operand.rs
@@ -416,7 +416,10 @@
                                 // FIXME: generate a panic here
                             },
                             mir::Literal::Value { .. } => {
-                                err.report(bx.tcx(), constant.span, "const operand");
+                                err.report_as_error(
+                                    bx.tcx().at(constant.span),
+                                    "could not evaluate constant operand",
+                                );
                             },
                         }
                         // We've errored, so we don't have to produce working code.
diff --git a/src/librustc_codegen_llvm/mir/place.rs b/src/librustc_codegen_llvm/mir/place.rs
index bda8c75..2a1e398 100644
--- a/src/librustc_codegen_llvm/mir/place.rs
+++ b/src/librustc_codegen_llvm/mir/place.rs
@@ -275,7 +275,11 @@
             layout::Variants::Single { .. } => bug!(),
             layout::Variants::Tagged { ref tag, .. } => {
                 let signed = match tag.value {
-                    layout::Int(_, signed) => signed,
+                    // We use `i1` for bytes that are always `0` or `1`,
+                    // e.g. `#[repr(i8)] enum E { A, B }`, but we can't
+                    // let LLVM interpret the `i1` as signed, because
+                    // then `i1 1` (i.e. E::B) is effectively `i8 -1`.
+                    layout::Int(_, signed) => !tag.is_bool() && signed,
                     _ => false
                 };
                 bx.intcast(lldiscr, cast_to, signed)
diff --git a/src/librustc_codegen_llvm/mir/rvalue.rs b/src/librustc_codegen_llvm/mir/rvalue.rs
index d1b949d..0fd81c6 100644
--- a/src/librustc_codegen_llvm/mir/rvalue.rs
+++ b/src/librustc_codegen_llvm/mir/rvalue.rs
@@ -298,7 +298,11 @@
                         let mut signed = false;
                         if let layout::Abi::Scalar(ref scalar) = operand.layout.abi {
                             if let layout::Int(_, s) = scalar.value {
-                                signed = s;
+                                // We use `i1` for bytes that are always `0` or `1`,
+                                // e.g. `#[repr(i8)] enum E { A, B }`, but we can't
+                                // let LLVM interpret the `i1` as signed, because
+                                // then `i1 1` (i.e. E::B) is effectively `i8 -1`.
+                                signed = !scalar.is_bool() && s;
 
                                 if scalar.valid_range.end() > scalar.valid_range.start() {
                                     // We want `table[e as usize]` to not
diff --git a/src/librustc_codegen_utils/codegen_backend.rs b/src/librustc_codegen_utils/codegen_backend.rs
index 15aab68..8ba6f30 100644
--- a/src/librustc_codegen_utils/codegen_backend.rs
+++ b/src/librustc_codegen_utils/codegen_backend.rs
@@ -39,7 +39,7 @@
 use rustc::session::{Session, CompileIncomplete};
 use rustc::session::config::{CrateType, OutputFilenames, PrintRequest};
 use rustc::ty::TyCtxt;
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::middle::cstore::EncodedMetadata;
 use rustc::middle::cstore::MetadataLoader;
 use rustc::dep_graph::DepGraph;
diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs
index 0c18571..d09e8f4 100644
--- a/src/librustc_codegen_utils/lib.rs
+++ b/src/librustc_codegen_utils/lib.rs
@@ -23,6 +23,8 @@
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
 
+#![recursion_limit="256"]
+
 extern crate ar;
 extern crate flate2;
 #[macro_use]
diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs
index 123816c..dcb82e5 100644
--- a/src/librustc_codegen_utils/symbol_names.rs
+++ b/src/librustc_codegen_utils/symbol_names.rs
@@ -103,7 +103,7 @@
 use rustc::ich::NodeIdHashingMode;
 use rustc::middle::weak_lang_items;
 use rustc::ty::item_path::{self, ItemPathBuffer, RootMode};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::ty::subst::Substs;
 use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc::util::common::record_time;
diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml
index 1595682..fc5fe91 100644
--- a/src/librustc_data_structures/Cargo.toml
+++ b/src/librustc_data_structures/Cargo.toml
@@ -16,7 +16,8 @@
 cfg-if = "0.1.2"
 stable_deref_trait = "1.0.0"
 parking_lot_core = "0.2.8"
-rustc-rayon = "0.1.0"
+rustc-rayon = "0.1.1"
+rustc-rayon-core = "0.1.1"
 rustc-hash = "1.0.1"
 
 [dependencies.parking_lot]
diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs
index 1fb63af..ad3710e 100644
--- a/src/librustc_data_structures/indexed_vec.rs
+++ b/src/librustc_data_structures/indexed_vec.rs
@@ -368,6 +368,11 @@
     }
 
     #[inline]
+    pub fn from_raw(raw: Vec<T>) -> Self {
+        IndexVec { raw, _marker: PhantomData }
+    }
+
+    #[inline]
     pub fn with_capacity(capacity: usize) -> Self {
         IndexVec { raw: Vec::with_capacity(capacity), _marker: PhantomData }
     }
diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs
index 23a9207..5844edf 100644
--- a/src/librustc_data_structures/lib.rs
+++ b/src/librustc_data_structures/lib.rs
@@ -44,6 +44,7 @@
 extern crate cfg_if;
 extern crate stable_deref_trait;
 extern crate rustc_rayon as rayon;
+extern crate rustc_rayon_core as rayon_core;
 extern crate rustc_hash;
 
 // See librustc_cratesio_shim/Cargo.toml for a comment explaining this.
@@ -79,6 +80,14 @@
 
 pub struct OnDrop<F: Fn()>(pub F);
 
+impl<F: Fn()> OnDrop<F> {
+      /// Forgets the function which prevents it from running.
+      /// Ensure that the function owns no memory, otherwise it will be leaked.
+      pub fn disable(self) {
+            std::mem::forget(self);
+      }
+}
+
 impl<F: Fn()> Drop for OnDrop<F> {
       fn drop(&mut self) {
             (self.0)();
diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs
index 612f44f..990dc66 100644
--- a/src/librustc_data_structures/obligation_forest/mod.rs
+++ b/src/librustc_data_structures/obligation_forest/mod.rs
@@ -41,7 +41,7 @@
 
     fn process_obligation(&mut self,
                           obligation: &mut Self::Obligation)
-                          -> Result<Option<Vec<Self::Obligation>>, Self::Error>;
+                          -> ProcessResult<Self::Obligation, Self::Error>;
 
     /// As we do the cycle check, we invoke this callback when we
     /// encounter an actual cycle. `cycle` is an iterator that starts
@@ -57,6 +57,14 @@
         where I: Clone + Iterator<Item=&'c Self::Obligation>;
 }
 
+/// The result type used by `process_obligation`.
+#[derive(Debug)]
+pub enum ProcessResult<O, E> {
+    Unchanged,
+    Changed(Vec<O>),
+    Error(E),
+}
+
 pub struct ObligationForest<O: ForestObligation> {
     /// The list of obligations. In between calls to
     /// `process_obligations`, this list only contains nodes in the
@@ -136,8 +144,8 @@
 
     /// If true, then we saw no successful obligations, which means
     /// there is no point in further iteration. This is based on the
-    /// assumption that when trait matching returns `Err` or
-    /// `Ok(None)`, those results do not affect environmental
+    /// assumption that when trait matching returns `Error` or
+    /// `Unchanged`, those results do not affect environmental
     /// inference state. (Note that if we invoke `process_obligations`
     /// with no pending obligations, stalled will be true.)
     pub stalled: bool,
@@ -229,13 +237,13 @@
     }
 
     /// Returns the set of obligations that are in a pending state.
-    pub fn pending_obligations(&self) -> Vec<O>
-        where O: Clone
+    pub fn map_pending_obligations<P, F>(&self, f: F) -> Vec<P>
+        where F: Fn(&O) -> P
     {
         self.nodes
             .iter()
             .filter(|n| n.state.get() == NodeState::Pending)
-            .map(|n| n.obligation.clone())
+            .map(|n| f(&n.obligation))
             .collect()
     }
 
@@ -270,11 +278,11 @@
                    result);
 
             match result {
-                Ok(None) => {
-                    // no change in state
+                ProcessResult::Unchanged => {
+                    // No change in state.
                 }
-                Ok(Some(children)) => {
-                    // if we saw a Some(_) result, we are not (yet) stalled
+                ProcessResult::Changed(children) => {
+                    // We are not (yet) stalled.
                     stalled = false;
                     self.nodes[index].state.set(NodeState::Success);
 
@@ -290,7 +298,7 @@
                         }
                     }
                 }
-                Err(err) => {
+                ProcessResult::Error(err) => {
                     stalled = false;
                     let backtrace = self.error_at(index);
                     errors.push(Error {
diff --git a/src/librustc_data_structures/obligation_forest/test.rs b/src/librustc_data_structures/obligation_forest/test.rs
index a95b2b8..527a1ef 100644
--- a/src/librustc_data_structures/obligation_forest/test.rs
+++ b/src/librustc_data_structures/obligation_forest/test.rs
@@ -10,7 +10,7 @@
 
 #![cfg(test)]
 
-use super::{ObligationForest, ObligationProcessor, Outcome, Error};
+use super::{Error, ObligationForest, ObligationProcessor, Outcome, ProcessResult};
 
 use std::fmt;
 use std::marker::PhantomData;
@@ -31,7 +31,7 @@
 
 #[allow(non_snake_case)]
 fn C<OF, BF, O>(of: OF, bf: BF) -> ClosureObligationProcessor<OF, BF, O, &'static str>
-    where OF: FnMut(&mut O) -> Result<Option<Vec<O>>, &'static str>,
+    where OF: FnMut(&mut O) -> ProcessResult<O, &'static str>,
           BF: FnMut(&[O])
 {
     ClosureObligationProcessor {
@@ -44,7 +44,7 @@
 impl<OF, BF, O, E> ObligationProcessor for ClosureObligationProcessor<OF, BF, O, E>
     where O: super::ForestObligation + fmt::Debug,
           E: fmt::Debug,
-          OF: FnMut(&mut O) -> Result<Option<Vec<O>>, E>,
+          OF: FnMut(&mut O) -> ProcessResult<O, E>,
           BF: FnMut(&[O])
 {
     type Obligation = O;
@@ -52,7 +52,7 @@
 
     fn process_obligation(&mut self,
                           obligation: &mut Self::Obligation)
-                          -> Result<Option<Vec<Self::Obligation>>, Self::Error>
+                          -> ProcessResult<Self::Obligation, Self::Error>
     {
         (self.process_obligation)(obligation)
     }
@@ -78,9 +78,9 @@
     let Outcome { completed: ok, errors: err, .. } =
         forest.process_obligations(&mut C(|obligation| {
             match *obligation {
-                "A" => Ok(Some(vec!["A.1", "A.2", "A.3"])),
-                "B" => Err("B is for broken"),
-                "C" => Ok(Some(vec![])),
+                "A" => ProcessResult::Changed(vec!["A.1", "A.2", "A.3"]),
+                "B" => ProcessResult::Error("B is for broken"),
+                "C" => ProcessResult::Changed(vec![]),
                 _ => unreachable!(),
             }
         }, |_| {}));
@@ -101,10 +101,10 @@
     let Outcome { completed: ok, errors: err, .. } =
         forest.process_obligations(&mut C(|obligation| {
             match *obligation {
-                "A.1" => Ok(None),
-                "A.2" => Ok(None),
-                "A.3" => Ok(Some(vec!["A.3.i"])),
-                "D" => Ok(Some(vec!["D.1", "D.2"])),
+                "A.1" => ProcessResult::Unchanged,
+                "A.2" => ProcessResult::Unchanged,
+                "A.3" => ProcessResult::Changed(vec!["A.3.i"]),
+                "D" => ProcessResult::Changed(vec!["D.1", "D.2"]),
                 _ => unreachable!(),
             }
         }, |_| {}));
@@ -119,11 +119,11 @@
     let Outcome { completed: ok, errors: err, .. } =
         forest.process_obligations(&mut C(|obligation| {
             match *obligation {
-                "A.1" => Ok(Some(vec![])),
-                "A.2" => Err("A is for apple"),
-                "A.3.i" => Ok(Some(vec![])),
-                "D.1" => Ok(Some(vec!["D.1.i"])),
-                "D.2" => Ok(Some(vec!["D.2.i"])),
+                "A.1" => ProcessResult::Changed(vec![]),
+                "A.2" => ProcessResult::Error("A is for apple"),
+                "A.3.i" => ProcessResult::Changed(vec![]),
+                "D.1" => ProcessResult::Changed(vec!["D.1.i"]),
+                "D.2" => ProcessResult::Changed(vec!["D.2.i"]),
                 _ => unreachable!(),
             }
         }, |_| {}));
@@ -138,8 +138,8 @@
     let Outcome { completed: ok, errors: err, .. } =
         forest.process_obligations(&mut C(|obligation| {
             match *obligation {
-                "D.1.i" => Err("D is for dumb"),
-                "D.2.i" => Ok(Some(vec![])),
+                "D.1.i" => ProcessResult::Error("D is for dumb"),
+                "D.2.i" => ProcessResult::Changed(vec![]),
                 _ => panic!("unexpected obligation {:?}", obligation),
             }
         }, |_| {}));
@@ -167,7 +167,7 @@
     let Outcome { completed: ok, errors: err, .. } =
         forest.process_obligations(&mut C(|obligation| {
             match *obligation {
-                "A" => Ok(Some(vec!["A.1", "A.2", "A.3"])),
+                "A" => ProcessResult::Changed(vec!["A.1", "A.2", "A.3"]),
                 _ => unreachable!(),
             }
         }, |_| {}));
@@ -177,9 +177,9 @@
     let Outcome { completed: ok, errors: err, .. } =
         forest.process_obligations(&mut C(|obligation| {
             match *obligation {
-                "A.1" => Ok(Some(vec![])),
-                "A.2" => Ok(Some(vec!["A.2.i", "A.2.ii"])),
-                "A.3" => Ok(Some(vec![])),
+                "A.1" => ProcessResult::Changed(vec![]),
+                "A.2" => ProcessResult::Changed(vec!["A.2.i", "A.2.ii"]),
+                "A.3" => ProcessResult::Changed(vec![]),
                 _ => unreachable!(),
             }
         }, |_| {}));
@@ -189,8 +189,8 @@
     let Outcome { completed: ok, errors: err, .. } =
         forest.process_obligations(&mut C(|obligation| {
             match *obligation {
-                "A.2.i" => Ok(Some(vec!["A.2.i.a"])),
-                "A.2.ii" => Ok(Some(vec![])),
+                "A.2.i" => ProcessResult::Changed(vec!["A.2.i.a"]),
+                "A.2.ii" => ProcessResult::Changed(vec![]),
                 _ => unreachable!(),
             }
         }, |_| {}));
@@ -200,7 +200,7 @@
     let Outcome { completed: ok, errors: err, .. } =
         forest.process_obligations(&mut C(|obligation| {
             match *obligation {
-                "A.2.i.a" => Ok(Some(vec![])),
+                "A.2.i.a" => ProcessResult::Changed(vec![]),
                 _ => unreachable!(),
             }
         }, |_| {}));
@@ -223,7 +223,7 @@
     let Outcome { completed: ok, errors: err, .. } =
         forest.process_obligations(&mut C(|obligation| {
             match *obligation {
-                "A" => Ok(Some(vec!["A.1", "A.2", "A.3"])),
+                "A" => ProcessResult::Changed(vec!["A.1", "A.2", "A.3"]),
                 _ => unreachable!(),
             }
         }, |_|{}));
@@ -244,7 +244,7 @@
     let Outcome { completed: ok, errors: err, .. } =
         forest.process_obligations(&mut C(|obligation| {
             match *obligation {
-                "A" => Ok(Some(vec!["A.1", "A.2"])),
+                "A" => ProcessResult::Changed(vec!["A.1", "A.2"]),
                 _ => unreachable!(),
             }
         }, |_|{}));
@@ -254,8 +254,8 @@
     let Outcome { completed: ok, errors: err, .. } =
         forest.process_obligations(&mut C(|obligation| {
             match *obligation {
-                "A.1" => Ok(Some(vec!["D"])),
-                "A.2" => Ok(Some(vec!["D"])),
+                "A.1" => ProcessResult::Changed(vec!["D"]),
+                "A.2" => ProcessResult::Changed(vec!["D"]),
                 _ => unreachable!(),
             }
         }, |_|{}));
@@ -266,7 +266,7 @@
     let Outcome { completed: ok, errors: err, .. } =
         forest.process_obligations(&mut C(|obligation| {
             match *obligation {
-                "D" => { d_count += 1; Ok(Some(vec![])) },
+                "D" => { d_count += 1; ProcessResult::Changed(vec![]) },
                 _ => unreachable!(),
             }
         }, |_|{}));
@@ -281,7 +281,7 @@
     let Outcome { completed: ok, errors: err, .. } =
         forest.process_obligations(&mut C(|obligation| {
             match *obligation {
-                "A'" => Ok(Some(vec!["A'.1", "A'.2"])),
+                "A'" => ProcessResult::Changed(vec!["A'.1", "A'.2"]),
                 _ => unreachable!(),
             }
         }, |_|{}));
@@ -291,8 +291,8 @@
     let Outcome { completed: ok, errors: err, .. } =
         forest.process_obligations(&mut C(|obligation| {
             match *obligation {
-                "A'.1" => Ok(Some(vec!["D'", "A'"])),
-                "A'.2" => Ok(Some(vec!["D'"])),
+                "A'.1" => ProcessResult::Changed(vec!["D'", "A'"]),
+                "A'.2" => ProcessResult::Changed(vec!["D'"]),
                 _ => unreachable!(),
             }
         }, |_|{}));
@@ -303,7 +303,7 @@
     let Outcome { completed: ok, errors: err, .. } =
         forest.process_obligations(&mut C(|obligation| {
             match *obligation {
-                "D'" => { d_count += 1; Err("operation failed") },
+                "D'" => { d_count += 1; ProcessResult::Error("operation failed") },
                 _ => unreachable!(),
             }
         }, |_|{}));
@@ -329,7 +329,7 @@
     let Outcome { completed: ok, errors: err, .. } =
         forest.process_obligations(&mut C(|obligation| {
             match *obligation {
-                "A: Sized" | "B: Sized" | "C: Sized" => Ok(Some(vec![])),
+                "A: Sized" | "B: Sized" | "C: Sized" => ProcessResult::Changed(vec![]),
                 _ => unreachable!(),
             }
         }, |_|{}));
@@ -340,11 +340,11 @@
     let Outcome { completed: ok, errors: err, .. } =
         forest.process_obligations(&mut C(|obligation| {
             match *obligation {
-                "(A,B,C): Sized" => Ok(Some(vec![
+                "(A,B,C): Sized" => ProcessResult::Changed(vec![
                     "A: Sized",
                     "B: Sized",
                     "C: Sized"
-                        ])),
+                        ]),
                 _ => unreachable!(),
             }
         }, |_|{}));
@@ -367,10 +367,10 @@
     let Outcome { completed: ok, errors: err, .. } =
         forest.process_obligations(&mut C(|obligation| {
             match *obligation {
-                "A" => Ok(Some(vec!["D", "E"])),
-                "B" => Ok(None),
-                "C1" => Ok(Some(vec![])),
-                "C2" => Ok(Some(vec![])),
+                "A" => ProcessResult::Changed(vec!["D", "E"]),
+                "B" => ProcessResult::Unchanged,
+                "C1" => ProcessResult::Changed(vec![]),
+                "C2" => ProcessResult::Changed(vec![]),
                 _ => unreachable!(),
             }
         }, |_|{}));
@@ -380,8 +380,8 @@
     let Outcome { completed: ok, errors: err, .. } =
         forest.process_obligations(&mut C(|obligation| {
             match *obligation {
-                "D" | "E" => Ok(None),
-                "B" => Ok(Some(vec!["D"])),
+                "D" | "E" => ProcessResult::Unchanged,
+                "B" => ProcessResult::Changed(vec!["D"]),
                 _ => unreachable!(),
             }
         }, |_|{}));
@@ -391,8 +391,8 @@
     let Outcome { completed: ok, errors: err, .. } =
         forest.process_obligations(&mut C(|obligation| {
             match *obligation {
-                "D" => Ok(None),
-                "E" => Err("E is for error"),
+                "D" => ProcessResult::Unchanged,
+                "E" => ProcessResult::Error("E is for error"),
                 _ => unreachable!(),
             }
         }, |_|{}));
@@ -405,7 +405,7 @@
     let Outcome { completed: ok, errors: err, .. } =
         forest.process_obligations(&mut C(|obligation| {
             match *obligation {
-                "D" => Err("D is dead"),
+                "D" => ProcessResult::Error("D is dead"),
                 _ => unreachable!(),
             }
         }, |_|{}));
@@ -429,8 +429,8 @@
     let Outcome { completed: ok, errors: err, .. } =
         forest.process_obligations(&mut C(|obligation| {
             match *obligation {
-                "A" => Err("An error"),
-                "B" => Ok(Some(vec!["A"])),
+                "A" => ProcessResult::Error("An error"),
+                "B" => ProcessResult::Changed(vec!["A"]),
                 _ => unreachable!(),
             }
         }, |_|{}));
@@ -447,8 +447,8 @@
     let Outcome { completed: ok, errors: err, .. } =
         forest.process_obligations(&mut C(|obligation| {
             match *obligation {
-                "A" => Err("An error"),
-                "B" => Ok(Some(vec!["A"])),
+                "A" => ProcessResult::Error("An error"),
+                "B" => ProcessResult::Changed(vec!["A"]),
                 _ => unreachable!(),
             }
         }, |_|{}));
diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs
index 3661763..33f6eda 100644
--- a/src/librustc_data_structures/sync.rs
+++ b/src/librustc_data_structures/sync.rs
@@ -36,7 +36,6 @@
 use std::fmt::Debug;
 use std::fmt::Formatter;
 use std::fmt;
-use std;
 use std::ops::{Deref, DerefMut};
 use owning_ref::{Erased, OwningRef};
 
@@ -101,6 +100,33 @@
         use std::cell::Cell;
 
         #[derive(Debug)]
+        pub struct WorkerLocal<T>(OneThread<T>);
+
+        impl<T> WorkerLocal<T> {
+            /// Creates a new worker local where the `initial` closure computes the
+            /// value this worker local should take for each thread in the thread pool.
+            #[inline]
+            pub fn new<F: FnMut(usize) -> T>(mut f: F) -> WorkerLocal<T> {
+                WorkerLocal(OneThread::new(f(0)))
+            }
+
+            /// Returns the worker-local value for each thread
+            #[inline]
+            pub fn into_inner(self) -> Vec<T> {
+                vec![OneThread::into_inner(self.0)]
+            }
+        }
+
+        impl<T> Deref for WorkerLocal<T> {
+            type Target = T;
+
+            #[inline(always)]
+            fn deref(&self) -> &T {
+                &*self.0
+            }
+        }
+
+        #[derive(Debug)]
         pub struct MTLock<T>(T);
 
         impl<T> MTLock<T> {
@@ -200,9 +226,12 @@
         use parking_lot::Mutex as InnerLock;
         use parking_lot::RwLock as InnerRwLock;
 
+        use std;
         use std::thread;
         pub use rayon::{join, scope};
 
+        pub use rayon_core::WorkerLocal;
+
         pub use rayon::iter::ParallelIterator;
         use rayon::iter::IntoParallelIterator;
 
@@ -492,6 +521,18 @@
 
     #[cfg(parallel_queries)]
     #[inline(always)]
+    pub fn try_lock(&self) -> Option<LockGuard<T>> {
+        self.0.try_lock()
+    }
+
+    #[cfg(not(parallel_queries))]
+    #[inline(always)]
+    pub fn try_lock(&self) -> Option<LockGuard<T>> {
+        self.0.try_borrow_mut().ok()
+    }
+
+    #[cfg(parallel_queries)]
+    #[inline(always)]
     pub fn lock(&self) -> LockGuard<T> {
         if ERROR_CHECKING {
             self.0.try_lock().expect("lock was already held")
@@ -638,7 +679,9 @@
     inner: T,
 }
 
+#[cfg(parallel_queries)]
 unsafe impl<T> std::marker::Sync for OneThread<T> {}
+#[cfg(parallel_queries)]
 unsafe impl<T> std::marker::Send for OneThread<T> {}
 
 impl<T> OneThread<T> {
diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml
index 24bf07d..5b75912 100644
--- a/src/librustc_driver/Cargo.toml
+++ b/src/librustc_driver/Cargo.toml
@@ -13,7 +13,7 @@
 graphviz = { path = "../libgraphviz" }
 log = "0.4"
 env_logger = { version = "0.5", default-features = false }
-rustc-rayon = "0.1.0"
+rustc-rayon = "0.1.1"
 scoped-tls = { version = "0.1.1", features = ["nightly"] }
 rustc = { path = "../librustc" }
 rustc_allocator = { path = "../librustc_allocator" }
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index ed28b05..5d5baf76 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -49,7 +49,7 @@
 use std::io::{self, Write};
 use std::iter;
 use std::path::{Path, PathBuf};
-use rustc_data_structures::sync::{self, Lrc};
+use rustc_data_structures::sync::{self, Lrc, Lock};
 use std::sync::mpsc;
 use syntax::{self, ast, attr, diagnostics, visit};
 use syntax::ext::base::ExtCtxt;
@@ -69,7 +69,9 @@
     opts: config::Options,
     f: F
 ) -> R {
-    f(opts)
+    ty::tls::GCX_PTR.set(&Lock::new(0), || {
+        f(opts)
+    })
 }
 
 #[cfg(parallel_queries)]
@@ -81,8 +83,12 @@
     use syntax_pos;
     use rayon::{ThreadPoolBuilder, ThreadPool};
 
-    let config = ThreadPoolBuilder::new().num_threads(Session::query_threads_from_opts(&opts))
-                                         .stack_size(16 * 1024 * 1024);
+    let gcx_ptr = &Lock::new(0);
+
+    let config = ThreadPoolBuilder::new()
+        .num_threads(Session::query_threads_from_opts(&opts))
+        .deadlock_handler(|| unsafe { ty::query::handle_deadlock() })
+        .stack_size(16 * 1024 * 1024);
 
     let with_pool = move |pool: &ThreadPool| {
         pool.install(move || f(opts))
@@ -98,7 +104,9 @@
                 syntax::GLOBALS.set(syntax_globals, || {
                     syntax_pos::GLOBALS.set(syntax_pos_globals, || {
                         ty::tls::with_thread_locals(|| {
-                            worker()
+                            ty::tls::GCX_PTR.set(gcx_ptr, || {
+                                worker()
+                            })
                         })
                     })
                 })
@@ -391,10 +399,10 @@
 
     /// Allows overriding default rustc query providers,
     /// after `default_provide` has installed them.
-    pub provide: Box<Fn(&mut ty::maps::Providers) + 'a>,
+    pub provide: Box<Fn(&mut ty::query::Providers) + 'a>,
     /// Same as `provide`, but only for non-local crates,
     /// applied after `default_provide_extern`.
-    pub provide_extern: Box<Fn(&mut ty::maps::Providers) + 'a>,
+    pub provide_extern: Box<Fn(&mut ty::query::Providers) + 'a>,
 }
 
 impl<'a> CompileController<'a> {
@@ -414,6 +422,75 @@
     }
 }
 
+/// This implementation makes it easier to create a custom driver when you only want to hook
+/// into callbacks from `CompileController`.
+///
+/// # Example
+///
+/// ```no_run
+/// # extern crate rustc_driver;
+/// # use rustc_driver::driver::CompileController;
+/// let mut controller = CompileController::basic();
+/// controller.after_analysis.callback = Box::new(move |_state| {});
+/// rustc_driver::run_compiler(&[], Box::new(controller), None, None);
+/// ```
+impl<'a> ::CompilerCalls<'a> for CompileController<'a> {
+    fn early_callback(
+        &mut self,
+        matches: &::getopts::Matches,
+        sopts: &config::Options,
+        cfg: &ast::CrateConfig,
+        descriptions: &::errors::registry::Registry,
+        output: ::ErrorOutputType,
+    ) -> Compilation {
+        ::RustcDefaultCalls.early_callback(
+            matches,
+            sopts,
+            cfg,
+            descriptions,
+            output,
+        )
+    }
+    fn no_input(
+        &mut self,
+        matches: &::getopts::Matches,
+        sopts: &config::Options,
+        cfg: &ast::CrateConfig,
+        odir: &Option<PathBuf>,
+        ofile: &Option<PathBuf>,
+        descriptions: &::errors::registry::Registry,
+    ) -> Option<(Input, Option<PathBuf>)> {
+        ::RustcDefaultCalls.no_input(
+            matches,
+            sopts,
+            cfg,
+            odir,
+            ofile,
+            descriptions,
+        )
+    }
+    fn late_callback(
+        &mut self,
+        codegen_backend: &::CodegenBackend,
+        matches: &::getopts::Matches,
+        sess: &Session,
+        cstore: &::CrateStore,
+        input: &Input,
+        odir: &Option<PathBuf>,
+        ofile: &Option<PathBuf>,
+    ) -> Compilation {
+        ::RustcDefaultCalls
+            .late_callback(codegen_backend, matches, sess, cstore, input, odir, ofile)
+    }
+    fn build_controller(
+        self: Box<Self>,
+        _: &Session,
+        _: &::getopts::Matches
+    ) -> CompileController<'a> {
+        *self
+    }
+}
+
 pub struct PhaseController<'a> {
     pub stop: Compilation,
     // If true then the compiler will try to run the callback even if the phase
@@ -1063,7 +1140,7 @@
     })
 }
 
-pub fn default_provide(providers: &mut ty::maps::Providers) {
+pub fn default_provide(providers: &mut ty::query::Providers) {
     hir::provide(providers);
     borrowck::provide(providers);
     mir::provide(providers);
@@ -1081,7 +1158,7 @@
     lint::provide(providers);
 }
 
-pub fn default_provide_extern(providers: &mut ty::maps::Providers) {
+pub fn default_provide_extern(providers: &mut ty::query::Providers) {
     cstore::provide_extern(providers);
 }
 
@@ -1126,7 +1203,7 @@
 
     time(sess, "loop checking", || loops::check_crate(sess, &hir_map));
 
-    let mut local_providers = ty::maps::Providers::default();
+    let mut local_providers = ty::query::Providers::default();
     default_provide(&mut local_providers);
     codegen_backend.provide(&mut local_providers);
     (control.provide)(&mut local_providers);
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 2f89814..67fd5da 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -454,7 +454,7 @@
 // See comments on CompilerCalls below for details about the callbacks argument.
 // The FileLoader provides a way to load files from sources other than the file system.
 pub fn run_compiler<'a>(args: &[String],
-                        callbacks: &mut (CompilerCalls<'a> + sync::Send),
+                        callbacks: Box<CompilerCalls<'a> + sync::Send + 'a>,
                         file_loader: Option<Box<FileLoader + Send + Sync + 'static>>,
                         emitter_dest: Option<Box<Write + Send>>)
                         -> (CompileResult, Option<Session>)
@@ -478,7 +478,7 @@
     matches: getopts::Matches,
     sopts: config::Options,
     cfg: ast::CrateConfig,
-    callbacks: &mut (CompilerCalls<'a> + sync::Send),
+    mut callbacks: Box<CompilerCalls<'a> + sync::Send + 'a>,
     file_loader: Option<Box<FileLoader + Send + Sync + 'static>>,
     emitter_dest: Option<Box<Write + Send>>
 ) -> (CompileResult, Option<Session>) {
@@ -642,12 +642,12 @@
     }
 }
 
-// A trait for customising the compilation process. Offers a number of hooks for
-// executing custom code or customising input.
+/// A trait for customising the compilation process. Offers a number of hooks for
+/// executing custom code or customising input.
 pub trait CompilerCalls<'a> {
-    // Hook for a callback early in the process of handling arguments. This will
-    // be called straight after options have been parsed but before anything
-    // else (e.g., selecting input and output).
+    /// Hook for a callback early in the process of handling arguments. This will
+    /// be called straight after options have been parsed but before anything
+    /// else (e.g., selecting input and output).
     fn early_callback(&mut self,
                       _: &getopts::Matches,
                       _: &config::Options,
@@ -658,9 +658,9 @@
         Compilation::Continue
     }
 
-    // Hook for a callback late in the process of handling arguments. This will
-    // be called just before actual compilation starts (and before build_controller
-    // is called), after all arguments etc. have been completely handled.
+    /// Hook for a callback late in the process of handling arguments. This will
+    /// be called just before actual compilation starts (and before build_controller
+    /// is called), after all arguments etc. have been completely handled.
     fn late_callback(&mut self,
                      _: &CodegenBackend,
                      _: &getopts::Matches,
@@ -673,9 +673,9 @@
         Compilation::Continue
     }
 
-    // Called after we extract the input from the arguments. Gives the implementer
-    // an opportunity to change the inputs or to add some custom input handling.
-    // The default behaviour is to simply pass through the inputs.
+    /// Called after we extract the input from the arguments. Gives the implementer
+    /// an opportunity to change the inputs or to add some custom input handling.
+    /// The default behaviour is to simply pass through the inputs.
     fn some_input(&mut self,
                   input: Input,
                   input_path: Option<PathBuf>)
@@ -683,11 +683,11 @@
         (input, input_path)
     }
 
-    // Called after we extract the input from the arguments if there is no valid
-    // input. Gives the implementer an opportunity to supply alternate input (by
-    // returning a Some value) or to add custom behaviour for this error such as
-    // emitting error messages. Returning None will cause compilation to stop
-    // at this point.
+    /// Called after we extract the input from the arguments if there is no valid
+    /// input. Gives the implementer an opportunity to supply alternate input (by
+    /// returning a Some value) or to add custom behaviour for this error such as
+    /// emitting error messages. Returning None will cause compilation to stop
+    /// at this point.
     fn no_input(&mut self,
                 _: &getopts::Matches,
                 _: &config::Options,
@@ -701,10 +701,14 @@
 
     // Create a CompilController struct for controlling the behaviour of
     // compilation.
-    fn build_controller(&mut self, _: &Session, _: &getopts::Matches) -> CompileController<'a>;
+    fn build_controller(
+        self: Box<Self>,
+        _: &Session,
+        _: &getopts::Matches
+    ) -> CompileController<'a>;
 }
 
-// CompilerCalls instance for a regular rustc build.
+/// CompilerCalls instance for a regular rustc build.
 #[derive(Copy, Clone)]
 pub struct RustcDefaultCalls;
 
@@ -878,7 +882,7 @@
             .and_then(|| RustcDefaultCalls::list_metadata(sess, cstore, matches, input))
     }
 
-    fn build_controller(&mut self,
+    fn build_controller(self: Box<Self>,
                         sess: &Session,
                         matches: &getopts::Matches)
                         -> CompileController<'a> {
@@ -1693,7 +1697,7 @@
             }))
             .collect::<Vec<_>>();
         run_compiler(&args,
-                     &mut RustcDefaultCalls,
+                     Box::new(RustcDefaultCalls),
                      None,
                      None)
     });
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index b22817a..9808e28 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -20,7 +20,7 @@
 use rustc::ty::subst::Subst;
 use rustc::traits::ObligationCause;
 use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
-use rustc::ty::maps::OnDiskCache;
+use rustc::ty::query::OnDiskCache;
 use rustc::infer::{self, InferOk, InferResult};
 use rustc::infer::outlives::env::OutlivesEnvironment;
 use rustc::infer::type_variable::TypeVariableOrigin;
@@ -157,8 +157,8 @@
     };
     TyCtxt::create_and_enter(&sess,
                              &cstore,
-                             ty::maps::Providers::default(),
-                             ty::maps::Providers::default(),
+                             ty::query::Providers::default(),
+                             ty::query::Providers::default(),
                              &arenas,
                              resolutions,
                              hir_map,
@@ -183,7 +183,7 @@
     });
 }
 
-const D1: ty::DebruijnIndex = ty::DebruijnIndex::INNERMOST;
+const D1: ty::DebruijnIndex = ty::INNERMOST;
 const D2: ty::DebruijnIndex = D1.shifted_in(1);
 
 impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
@@ -191,11 +191,12 @@
         self.infcx.tcx
     }
 
-    pub fn create_region_hierarchy(&mut self, rh: &RH, parent: region::Scope) {
+    pub fn create_region_hierarchy(&mut self, rh: &RH,
+                                   parent: (region::Scope, region::ScopeDepth)) {
         let me = region::Scope::Node(rh.id);
         self.region_scope_tree.record_scope_parent(me, Some(parent));
         for child_rh in rh.sub {
-            self.create_region_hierarchy(child_rh, me);
+            self.create_region_hierarchy(child_rh, (me, parent.1 + 1));
         }
     }
 
@@ -215,7 +216,7 @@
                 id: hir::ItemLocalId(11),
                 sub: &[],
             }],
-        }, dscope);
+        }, (dscope, 1));
     }
 
     #[allow(dead_code)] // this seems like it could be useful, even if we don't use it now
@@ -255,6 +256,7 @@
                 hir::ItemFn(..) |
                 hir::ItemForeignMod(..) |
                 hir::ItemGlobalAsm(..) |
+                hir::ItemExistential(..) |
                 hir::ItemTy(..) => None,
 
                 hir::ItemEnum(..) |
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index f65acf0..92e72fe 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -1287,7 +1287,7 @@
                         });
 
                         // length of the code to be substituted
-                        let snippet_len = (span_end_pos - span_start_pos) as isize;
+                        let snippet_len = span_end_pos as isize - span_start_pos as isize;
                         // For multiple substitutions, use the position *after* the previous
                         // substitutions have happened.
                         offset += full_sub_len - snippet_len;
diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs
index 1549ef5..eeb87e4 100644
--- a/src/librustc_incremental/persist/dirty_clean.rs
+++ b/src/librustc_incremental/persist/dirty_clean.rs
@@ -385,7 +385,7 @@
                     // michaelwoerister and vitiral came up with a possible solution,
                     // to just do this before every query
                     // ```
-                    // ::rustc::ty::maps::plumbing::force_from_dep_node(tcx, dep_node)
+                    // ::rustc::ty::query::plumbing::force_from_dep_node(tcx, dep_node)
                     // ```
                     //
                     // However, this did not seem to work effectively and more bugs were hit.
diff --git a/src/librustc_incremental/persist/load.rs b/src/librustc_incremental/persist/load.rs
index f846759..9ee3b21 100644
--- a/src/librustc_incremental/persist/load.rs
+++ b/src/librustc_incremental/persist/load.rs
@@ -14,7 +14,7 @@
 use rustc::dep_graph::{PreviousDepGraph, SerializedDepGraph, WorkProduct, WorkProductId};
 use rustc::session::Session;
 use rustc::ty::TyCtxt;
-use rustc::ty::maps::OnDiskCache;
+use rustc::ty::query::OnDiskCache;
 use rustc::util::common::time_ext;
 use rustc_serialize::Decodable as RustcDecodable;
 use rustc_serialize::opaque::Decoder;
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 8a08505..79796d7 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -673,6 +673,79 @@
     }
 }
 
+/// Checks for incorrect use use of `repr` attributes.
+#[derive(Clone)]
+pub struct BadRepr;
+
+impl LintPass for BadRepr {
+    fn get_lints(&self) -> LintArray {
+        lint_array!()
+    }
+}
+
+impl EarlyLintPass for BadRepr {
+    fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) {
+        if attr.name() == "repr" {
+            let list = attr.meta_item_list();
+
+            let repr_str = |lit: &str| { format!("#[repr({})]", lit) };
+
+            // Emit warnings with `repr` either has a literal assignment (`#[repr = "C"]`) or
+            // no hints (``#[repr]`)
+            let has_hints = list.as_ref().map(|ref list| !list.is_empty()).unwrap_or(false);
+            if !has_hints {
+                let mut suggested = false;
+                let mut warn = if let Some(ref lit) = attr.value_str() {
+                    // avoid warning about empty `repr` on `#[repr = "foo"]`
+                    let mut warn = cx.struct_span_lint(
+                        BAD_REPR,
+                        attr.span,
+                        "`repr` attribute isn't configurable with a literal",
+                    );
+                    match format!("{}", lit).as_ref() {
+                        | "C" | "packed" | "rust" | "transparent"
+                        | "u8" | "u16" | "u32" | "u64" | "u128" | "usize"
+                        | "i8" | "i16" | "i32" | "i64" | "i128" | "isize" => {
+                            // if the literal could have been a valid `repr` arg,
+                            // suggest the correct syntax
+                            warn.span_suggestion(
+                                attr.span,
+                                "give `repr` a hint",
+                                repr_str(&lit.as_str()),
+                            );
+                            suggested = true;
+                        }
+                        _ => {  // the literal wasn't a valid `repr` arg
+                            warn.span_label(attr.span, "needs a hint");
+                        }
+                    };
+                    warn
+                } else {
+                    let mut warn = cx.struct_span_lint(
+                        BAD_REPR,
+                        attr.span,
+                        "`repr` attribute must have a hint",
+                    );
+                    warn.span_label(attr.span, "needs a hint");
+                    warn
+                };
+                if !suggested {
+                    warn.help(&format!(
+                        "valid hints include `{}`, `{}`, `{}` and `{}`",
+                        repr_str("C"),
+                        repr_str("packed"),
+                        repr_str("rust"),
+                        repr_str("transparent"),
+                    ));
+                    warn.note("for more information, visit \
+                               <https://doc.rust-lang.org/reference/type-layout.html>");
+                }
+                warn.emit();
+            }
+        }
+    }
+}
+
 /// Checks for use of attributes which have been deprecated.
 #[derive(Clone)]
 pub struct DeprecatedAttr {
@@ -1501,24 +1574,11 @@
     };
     if let Err(err) = cx.tcx.const_eval(param_env.and(cid)) {
         let span = cx.tcx.def_span(def_id);
-        let mut diag = cx.struct_span_lint(
-            CONST_ERR,
-            span,
+        err.report_as_lint(
+            cx.tcx.at(span),
             &format!("this {} cannot be used", what),
+            cx.current_lint_root(),
         );
-        use rustc::middle::const_val::ConstEvalErrDescription;
-        match err.description() {
-            ConstEvalErrDescription::Simple(message) => {
-                diag.span_label(span, message);
-            }
-            ConstEvalErrDescription::Backtrace(miri, frames) => {
-                diag.span_label(span, format!("{}", miri));
-                for frame in frames {
-                    diag.span_label(frame.span, format!("inside call to `{}`", frame.location));
-                }
-            }
-        }
-        diag.emit()
     }
 }
 
@@ -1548,72 +1608,6 @@
     }
 }
 
-declare_lint! {
-    pub UNNECESSARY_EXTERN_CRATES,
-    Allow,
-    "suggest removing `extern crate` for the 2018 edition"
-}
-
-pub struct ExternCrate(/* depth */ u32);
-
-impl ExternCrate {
-    pub fn new() -> Self {
-        ExternCrate(0)
-    }
-}
-
-impl LintPass for ExternCrate {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(UNNECESSARY_EXTERN_CRATES)
-    }
-}
-
-impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExternCrate {
-    fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
-        if !cx.tcx.features().extern_absolute_paths {
-            return
-        }
-        if let hir::ItemExternCrate(ref orig) =  it.node {
-            if it.attrs.iter().any(|a| a.check_name("macro_use")) {
-                return
-            }
-            let mut err = cx.struct_span_lint(UNNECESSARY_EXTERN_CRATES,
-                it.span, "`extern crate` is unnecessary in the new edition");
-            if it.vis == hir::Visibility::Public || self.0 > 1 || orig.is_some() {
-                let pub_ = if it.vis == hir::Visibility::Public {
-                    "pub "
-                } else {
-                    ""
-                };
-
-                let help = format!("use `{}use`", pub_);
-
-                if let Some(orig) = orig {
-                    err.span_suggestion(it.span, &help,
-                        format!("{}use {} as {};", pub_, orig, it.name));
-                } else {
-                    err.span_suggestion(it.span, &help,
-                        format!("{}use {};", pub_, it.name));
-                }
-            } else {
-                err.span_suggestion(it.span, "remove it", "".into());
-            }
-
-            err.emit();
-        }
-    }
-
-    fn check_mod(&mut self, _: &LateContext, _: &hir::Mod,
-                 _: Span, _: ast::NodeId) {
-        self.0 += 1;
-    }
-
-    fn check_mod_post(&mut self, _: &LateContext, _: &hir::Mod,
-                      _: Span, _: ast::NodeId) {
-        self.0 += 1;
-    }
-}
-
 /// Lint for trait and lifetime bounds that don't depend on type parameters
 /// which either do nothing, or stop the item from being used.
 pub struct TrivialConstraints;
@@ -1671,3 +1665,36 @@
         }
     }
 }
+
+/// Does nothing as a lint pass, but registers some `Lint`s
+/// which are used by other parts of the compiler.
+#[derive(Copy, Clone)]
+pub struct SoftLints;
+
+impl LintPass for SoftLints {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(
+            WHILE_TRUE,
+            BOX_POINTERS,
+            NON_SHORTHAND_FIELD_PATTERNS,
+            UNSAFE_CODE,
+            MISSING_DOCS,
+            MISSING_COPY_IMPLEMENTATIONS,
+            MISSING_DEBUG_IMPLEMENTATIONS,
+            ANONYMOUS_PARAMETERS,
+            UNUSED_DOC_COMMENTS,
+            UNCONDITIONAL_RECURSION,
+            PLUGIN_AS_LIBRARY,
+            PRIVATE_NO_MANGLE_FNS,
+            PRIVATE_NO_MANGLE_STATICS,
+            NO_MANGLE_CONST_ITEMS,
+            NO_MANGLE_GENERIC_ITEMS,
+            MUTABLE_TRANSMUTES,
+            UNSTABLE_FEATURES,
+            UNIONS_WITH_DROP_FIELDS,
+            UNREACHABLE_PUB,
+            TYPE_ALIAS_BOUNDS,
+            TRIVIAL_BOUNDS,
+        )
+    }
+}
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index c5994d0..9ac22f8 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -60,6 +60,9 @@
 use types::*;
 use unused::*;
 
+/// Useful for other parts of the compiler.
+pub use builtin::SoftLints;
+
 /// Tell the `LintStore` about all the built-in lints (the ones
 /// defined in this crate and the ones defined in
 /// `rustc::lint::builtin`).
@@ -107,6 +110,7 @@
                        UnusedImportBraces,
                        AnonymousParameters,
                        UnusedDocComment,
+                       BadRepr,
                        );
 
     add_early_builtin_with_new!(sess,
@@ -145,7 +149,6 @@
                           TypeLimits,
                           MissingDoc,
                           MissingDebugImplementations,
-                          ExternCrate,
                           );
 
     add_lint_group!(sess,
@@ -185,7 +188,7 @@
                     "rust_2018_idioms",
                     BARE_TRAIT_OBJECTS,
                     UNREACHABLE_PUB,
-                    UNNECESSARY_EXTERN_CRATES);
+                    UNUSED_EXTERN_CRATES);
 
     // Guidelines for creating a future incompatibility lint:
     //
@@ -213,6 +216,11 @@
             edition: None,
         },
         FutureIncompatibleInfo {
+            id: LintId::of(DUPLICATE_MACRO_EXPORTS),
+            reference: "issue #35896 <https://github.com/rust-lang/rust/issues/35896>",
+            edition: Some(Edition::Edition2018),
+        },
+        FutureIncompatibleInfo {
             id: LintId::of(SAFE_EXTERN_STATICS),
             reference: "issue #36247 <https://github.com/rust-lang/rust/issues/36247>",
             edition: None,
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 845c964..81b4ae3 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -393,7 +393,7 @@
             // Trigger the lint if the nested item is a non-self single item
             let node_ident;
             match items[0].0.kind {
-                ast::UseTreeKind::Simple(rename) => {
+                ast::UseTreeKind::Simple(rename, ..) => {
                     let orig_ident = items[0].0.prefix.segments.last().unwrap().ident;
                     if orig_ident.name == keywords::SelfValue.name() {
                         return;
diff --git a/src/librustc_lsan/lib.rs b/src/librustc_lsan/lib.rs
index 81a09e7..a7aeed7 100644
--- a/src/librustc_lsan/lib.rs
+++ b/src/librustc_lsan/lib.rs
@@ -9,10 +9,9 @@
 // except according to those terms.
 
 #![sanitizer_runtime]
-#![feature(sanitizer_runtime)]
 #![feature(alloc_system)]
-#![feature(allocator_api)]
-#![feature(global_allocator)]
+#![cfg_attr(stage0, feature(global_allocator))]
+#![feature(sanitizer_runtime)]
 #![feature(staged_api)]
 #![no_std]
 #![unstable(feature = "sanitizer_runtime_lib",
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 4691027..b33d97c 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -15,7 +15,7 @@
 use foreign_modules;
 use schema;
 
-use rustc::ty::maps::QueryConfig;
+use rustc::ty::query::QueryConfig;
 use rustc::middle::cstore::{CrateStore, DepKind,
                             MetadataLoader, LinkMeta,
                             LoadedMacro, EncodedMetadata, NativeLibraryKind};
@@ -24,7 +24,7 @@
 use rustc::hir::def;
 use rustc::session::{CrateDisambiguator, Session};
 use rustc::ty::{self, TyCtxt};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE, CRATE_DEF_INDEX};
 use rustc::hir::map::{DefKey, DefPath, DefPathHash};
 use rustc::hir::map::blocks::FnLikeNode;
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 69e873b..9e4f695 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -419,6 +419,7 @@
             EntryKind::ForeignFn(_) => Def::Fn(did),
             EntryKind::Method(_) => Def::Method(did),
             EntryKind::Type => Def::TyAlias(did),
+            EntryKind::Existential => Def::Existential(did),
             EntryKind::AssociatedType(_) => Def::AssociatedTy(did),
             EntryKind::Mod(_) => Def::Mod(did),
             EntryKind::Variant(_) => Def::Variant(did),
@@ -665,7 +666,6 @@
                         def: def,
                         vis: ty::Visibility::Public,
                         span: DUMMY_SP,
-                        is_import: false,
                     });
                 }
             }
@@ -705,7 +705,6 @@
                                     ident: Ident::from_interned_str(self.item_name(child_index)),
                                     vis: self.get_visibility(child_index),
                                     span: self.entry(child_index).span.decode((self, sess)),
-                                    is_import: false,
                                 });
                             }
                         }
@@ -722,8 +721,7 @@
                     (self.get_def(child_index), def_key.disambiguated_data.data.get_opt_name()) {
                     let ident = Ident::from_interned_str(name);
                     let vis = self.get_visibility(child_index);
-                    let is_import = false;
-                    callback(def::Export { def, ident, vis, span, is_import });
+                    callback(def::Export { def, ident, vis, span });
                     // For non-re-export structs and variants add their constructors to children.
                     // Re-export lists automatically contain constructors when necessary.
                     match def {
@@ -734,7 +732,7 @@
                                 callback(def::Export {
                                     def: ctor_def,
                                     vis: self.get_visibility(ctor_def_id.index),
-                                    ident, span, is_import,
+                                    ident, span,
                                 });
                             }
                         }
@@ -744,7 +742,7 @@
                             let ctor_kind = self.get_ctor_kind(child_index);
                             let ctor_def = Def::VariantCtor(def_id, ctor_kind);
                             let vis = self.get_visibility(child_index);
-                            callback(def::Export { def: ctor_def, ident, vis, span, is_import });
+                            callback(def::Export { def: ctor_def, ident, vis, span });
                         }
                         _ => {}
                     }
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index ab30ff7..33d4df1 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -1060,6 +1060,7 @@
             hir::ItemForeignMod(_) => EntryKind::ForeignMod,
             hir::ItemGlobalAsm(..) => EntryKind::GlobalAsm,
             hir::ItemTy(..) => EntryKind::Type,
+            hir::ItemExistential(..) => EntryKind::Existential,
             hir::ItemEnum(..) => EntryKind::Enum(get_repr_options(&tcx, def_id)),
             hir::ItemStruct(ref struct_def, _) => {
                 let variant = tcx.adt_def(def_id).non_enum_variant();
@@ -1187,6 +1188,7 @@
                 hir::ItemConst(..) |
                 hir::ItemFn(..) |
                 hir::ItemTy(..) |
+                hir::ItemExistential(..) |
                 hir::ItemEnum(..) |
                 hir::ItemStruct(..) |
                 hir::ItemUnion(..) |
@@ -1210,6 +1212,7 @@
                 hir::ItemStruct(..) |
                 hir::ItemUnion(..) |
                 hir::ItemImpl(..) |
+                hir::ItemExistential(..) |
                 hir::ItemTrait(..) => Some(self.encode_generics(def_id)),
                 _ => None,
             },
@@ -1222,6 +1225,7 @@
                 hir::ItemStruct(..) |
                 hir::ItemUnion(..) |
                 hir::ItemImpl(..) |
+                hir::ItemExistential(..) |
                 hir::ItemTrait(..) => Some(self.encode_predicates(def_id)),
                 _ => None,
             },
@@ -1301,28 +1305,6 @@
         }
     }
 
-    fn encode_info_for_anon_ty(&mut self, def_id: DefId) -> Entry<'tcx> {
-        debug!("IsolatedEncoder::encode_info_for_anon_ty({:?})", def_id);
-        let tcx = self.tcx;
-        Entry {
-            kind: EntryKind::Type,
-            visibility: self.lazy(&ty::Visibility::Public),
-            span: self.lazy(&tcx.def_span(def_id)),
-            attributes: LazySeq::empty(),
-            children: LazySeq::empty(),
-            stability: None,
-            deprecation: None,
-
-            ty: Some(self.encode_item_type(def_id)),
-            inherent_impls: LazySeq::empty(),
-            variances: LazySeq::empty(),
-            generics: Some(self.encode_generics(def_id)),
-            predicates: Some(self.encode_predicates(def_id)),
-
-            mir: None,
-        }
-    }
-
     fn encode_info_for_closure(&mut self, def_id: DefId) -> Entry<'tcx> {
         debug!("IsolatedEncoder::encode_info_for_closure({:?})", def_id);
         let tcx = self.tcx;
@@ -1672,10 +1654,6 @@
 
     fn encode_info_for_ty(&mut self, ty: &hir::Ty) {
         match ty.node {
-            hir::TyImplTraitExistential(..) => {
-                let def_id = self.tcx.hir.local_def_id(ty.id);
-                self.record(def_id, IsolatedEncoder::encode_info_for_anon_ty, def_id);
-            }
             hir::TyArray(_, ref length) => {
                 let def_id = self.tcx.hir.local_def_id(length.id);
                 self.record(def_id, IsolatedEncoder::encode_info_for_anon_const, def_id);
@@ -1710,6 +1688,7 @@
             hir::ItemExternCrate(..) |
             hir::ItemUse(..) |
             hir::ItemTy(..) |
+            hir::ItemExistential(..) |
             hir::ItemTraitAlias(..) => {
                 // no sub-item recording needed in these cases
             }
diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs
index 7ecf2eb..d76ca5b 100644
--- a/src/librustc_metadata/lib.rs
+++ b/src/librustc_metadata/lib.rs
@@ -23,6 +23,8 @@
 #![feature(specialization)]
 #![feature(rustc_private)]
 
+#![recursion_limit="256"]
+
 extern crate libc;
 #[macro_use]
 extern crate log;
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index 2e89ea6..21d6d15 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -304,6 +304,7 @@
     ForeignType,
     GlobalAsm,
     Type,
+    Existential,
     Enum(ReprOptions),
     Field,
     Variant(Lazy<VariantData<'tcx>>),
@@ -336,6 +337,7 @@
             EntryKind::GlobalAsm        |
             EntryKind::ForeignType      |
             EntryKind::Field |
+            EntryKind::Existential |
             EntryKind::Type => {
                 // Nothing else to hash here.
             }
diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml
index 512ab53..0fd1f92 100644
--- a/src/librustc_mir/Cargo.toml
+++ b/src/librustc_mir/Cargo.toml
@@ -15,7 +15,7 @@
 graphviz = { path = "../libgraphviz" }
 log = "0.4"
 log_settings = "0.1.1"
-polonius-engine = "0.4.0"
+polonius-engine = "0.5.0"
 rustc = { path = "../librustc" }
 rustc_target = { path = "../librustc_target" }
 rustc_data_structures = { path = "../librustc_data_structures" }
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 5efbdea..c43ea03 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -16,7 +16,7 @@
 use rustc::hir::map::definitions::DefPathData;
 use rustc::infer::InferCtxt;
 use rustc::ty::{self, ParamEnv, TyCtxt};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::lint::builtin::UNUSED_MUT;
 use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
 use rustc::mir::{ClearCrossCrate, Local, Location, Place, Mir, Mutability, Operand};
@@ -132,14 +132,21 @@
                     IllegalMoveOriginKind::Static => {
                         tcx.cannot_move_out_of(span, "static item", origin)
                     }
-                    IllegalMoveOriginKind::BorrowedContent => {
-                        tcx.cannot_move_out_of(span, "borrowed content", origin)
+                    IllegalMoveOriginKind::BorrowedContent { target_ty: ty } => {
+                        // Inspect the type of the content behind the
+                        // borrow to provide feedback about why this
+                        // was a move rather than a copy.
+                        match ty.sty {
+                            ty::TyArray(..) | ty::TySlice(..) =>
+                                tcx.cannot_move_out_of_interior_noncopy(span, ty, None, origin),
+                            _ => tcx.cannot_move_out_of(span, "borrowed content", origin)
+                        }
                     }
                     IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => {
                         tcx.cannot_move_out_of_interior_of_drop(span, ty, origin)
                     }
                     IllegalMoveOriginKind::InteriorOfSliceOrArray { ty, is_index } => {
-                        tcx.cannot_move_out_of_interior_noncopy(span, ty, is_index, origin)
+                        tcx.cannot_move_out_of_interior_noncopy(span, ty, Some(is_index), origin)
                     }
                 };
                 err.emit();
diff --git a/src/librustc_mir/borrow_check/nll/constraint_generation.rs b/src/librustc_mir/borrow_check/nll/constraint_generation.rs
index 4f87a2b..72db9f8 100644
--- a/src/librustc_mir/borrow_check/nll/constraint_generation.rs
+++ b/src/librustc_mir/borrow_check/nll/constraint_generation.rs
@@ -11,6 +11,8 @@
 use borrow_check::borrow_set::BorrowSet;
 use borrow_check::location::LocationTable;
 use borrow_check::nll::facts::AllFacts;
+use borrow_check::nll::region_infer::{Cause, RegionInferenceContext};
+use borrow_check::nll::ToRegionVid;
 use rustc::hir;
 use rustc::infer::InferCtxt;
 use rustc::mir::visit::TyContext;
@@ -21,9 +23,7 @@
 use rustc::ty::fold::TypeFoldable;
 use rustc::ty::subst::Substs;
 use rustc::ty::{self, CanonicalTy, ClosureSubsts, GeneratorSubsts};
-
-use super::region_infer::{Cause, RegionInferenceContext};
-use super::ToRegionVid;
+use std::iter;
 
 pub(super) fn generate_constraints<'cx, 'gcx, 'tcx>(
     infcx: &InferCtxt<'cx, 'gcx, 'tcx>,
@@ -32,6 +32,7 @@
     location_table: &LocationTable,
     mir: &Mir<'tcx>,
     borrow_set: &BorrowSet<'tcx>,
+    liveness_set_from_typeck: &[(ty::Region<'tcx>, Location, Cause)],
 ) {
     let mut cg = ConstraintGeneration {
         borrow_set,
@@ -42,6 +43,8 @@
         mir,
     };
 
+    cg.add_region_liveness_constraints_from_type_check(liveness_set_from_typeck);
+
     for (bb, data) in mir.basic_blocks().iter_enumerated() {
         cg.visit_basic_block_data(bb, data);
     }
@@ -209,7 +212,7 @@
                 self.add_reborrow_constraint(location, region, borrowed_place);
             }
 
-            _ => { }
+            _ => {}
         }
 
         self.super_rvalue(rvalue, location);
@@ -225,6 +228,42 @@
 }
 
 impl<'cx, 'cg, 'gcx, 'tcx> ConstraintGeneration<'cx, 'cg, 'gcx, 'tcx> {
+    /// The MIR type checker generates region liveness constraints
+    /// that we also have to respect.
+    fn add_region_liveness_constraints_from_type_check(
+        &mut self,
+        liveness_set: &[(ty::Region<'tcx>, Location, Cause)],
+    ) {
+        debug!(
+            "add_region_liveness_constraints_from_type_check(liveness_set={} items)",
+            liveness_set.len(),
+        );
+
+        let ConstraintGeneration {
+            regioncx,
+            location_table,
+            all_facts,
+            ..
+        } = self;
+
+        for (region, location, cause) in liveness_set {
+            debug!("generate: {:#?} is live at {:#?}", region, location);
+            let region_vid = regioncx.to_region_vid(region);
+            regioncx.add_live_point(region_vid, *location, &cause);
+        }
+
+        if let Some(all_facts) = all_facts {
+            all_facts
+                .region_live_at
+                .extend(liveness_set.into_iter().flat_map(|(region, location, _)| {
+                    let r = regioncx.to_region_vid(region);
+                    let p1 = location_table.start_index(*location);
+                    let p2 = location_table.mid_index(*location);
+                    iter::once((r, p1)).chain(iter::once((r, p2)))
+                }));
+        }
+    }
+
     /// Some variable with type `live_ty` is "regular live" at
     /// `location` -- i.e., it may be used later. This means that all
     /// regions appearing in the type `live_ty` must be live at
diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs
index ec1f3db..dcb52a3 100644
--- a/src/librustc_mir/borrow_check/nll/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/mod.rs
@@ -11,6 +11,7 @@
 use borrow_check::borrow_set::BorrowSet;
 use borrow_check::location::{LocationIndex, LocationTable};
 use borrow_check::nll::facts::AllFactsExt;
+use borrow_check::nll::type_check::MirTypeckRegionConstraints;
 use dataflow::indexes::BorrowIndex;
 use dataflow::move_paths::MoveData;
 use dataflow::FlowAtLocation;
@@ -22,9 +23,11 @@
 use rustc::util::nodemap::FxHashMap;
 use std::collections::BTreeSet;
 use std::fmt::Debug;
+use std::env;
 use std::io;
 use std::path::PathBuf;
 use std::rc::Rc;
+use std::str::FromStr;
 use transform::MirSource;
 use util::liveness::{LivenessResults, LocalSet};
 
@@ -39,7 +42,6 @@
 mod invalidation;
 crate mod region_infer;
 mod renumber;
-mod subtype_constraint_generation;
 crate mod type_check;
 mod universal_regions;
 
@@ -89,19 +91,6 @@
     Option<Rc<Output<RegionVid, BorrowIndex, LocationIndex>>>,
     Option<ClosureRegionRequirements<'gcx>>,
 ) {
-    // Run the MIR type-checker.
-    let liveness = &LivenessResults::compute(mir);
-    let constraint_sets = &type_check::type_check(
-        infcx,
-        param_env,
-        mir,
-        def_id,
-        &universal_regions,
-        &liveness,
-        flow_inits,
-        move_data,
-    );
-
     let mut all_facts = if infcx.tcx.sess.opts.debugging_opts.nll_facts
         || infcx.tcx.sess.opts.debugging_opts.polonius
     {
@@ -110,25 +99,45 @@
         None
     };
 
+    // Run the MIR type-checker.
+    let liveness = &LivenessResults::compute(mir);
+    let constraint_sets = type_check::type_check(
+        infcx,
+        param_env,
+        mir,
+        def_id,
+        &universal_regions,
+        location_table,
+        &liveness,
+        &mut all_facts,
+        flow_inits,
+        move_data,
+    );
+
     if let Some(all_facts) = &mut all_facts {
         all_facts
             .universal_region
             .extend(universal_regions.universal_regions());
     }
 
-    // Create the region inference context, taking ownership of the region inference
-    // data that was contained in `infcx`.
+    // Create the region inference context, taking ownership of the
+    // region inference data that was contained in `infcx`, and the
+    // base constraints generated by the type-check.
     let var_origins = infcx.take_region_var_origins();
-    let mut regioncx = RegionInferenceContext::new(var_origins, universal_regions, mir);
-
-    // Generate various constraints.
-    subtype_constraint_generation::generate(
-        &mut regioncx,
-        &mut all_facts,
-        location_table,
+    let MirTypeckRegionConstraints {
+        liveness_set,
+        outlives_constraints,
+        type_tests,
+    } = constraint_sets;
+    let mut regioncx = RegionInferenceContext::new(
+        var_origins,
+        universal_regions,
         mir,
-        constraint_sets,
+        outlives_constraints,
+        type_tests,
     );
+
+    // Generate various additional constraints.
     constraint_generation::generate_constraints(
         infcx,
         &mut regioncx,
@@ -136,6 +145,7 @@
         location_table,
         &mir,
         borrow_set,
+        &liveness_set,
     );
     invalidation::generate_invalidates(
         infcx,
@@ -156,9 +166,13 @@
         }
 
         if infcx.tcx.sess.opts.debugging_opts.polonius {
+            let algorithm = env::var("POLONIUS_ALGORITHM")
+                .unwrap_or(String::from("DatafrogOpt"));
+            let algorithm = Algorithm::from_str(&algorithm).unwrap();
+            debug!("compute_regions: using polonius algorithm {:?}", algorithm);
             Some(Rc::new(Output::compute(
                 &all_facts,
-                Algorithm::DatafrogOpt,
+                algorithm,
                 false,
             )))
         } else {
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs b/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs
index b0346ab..6c796ea 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs
@@ -14,7 +14,7 @@
 //! context internal state.
 
 use std::io::{self, Write};
-use super::{Constraint, RegionInferenceContext};
+use super::{OutlivesConstraint, RegionInferenceContext};
 
 // Room for "'_#NNNNr" before things get misaligned.
 // Easy enough to fix if this ever doesn't seem like
@@ -79,7 +79,7 @@
         let mut constraints: Vec<_> = self.constraints.iter().collect();
         constraints.sort();
         for constraint in &constraints {
-            let Constraint {
+            let OutlivesConstraint {
                 sup,
                 sub,
                 point,
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs b/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs
index 6c4c02a..c02e4ff 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs
@@ -27,7 +27,7 @@
 
 impl<'this, 'tcx> dot::Labeller<'this> for RegionInferenceContext<'tcx> {
     type Node = RegionVid;
-    type Edge = Constraint;
+    type Edge = OutlivesConstraint;
 
     fn graph_id(&'this self) -> dot::Id<'this> {
         dot::Id::new(format!("RegionInferenceContext")).unwrap()
@@ -41,31 +41,31 @@
     fn node_label(&'this self, n: &RegionVid) -> dot::LabelText<'this> {
         dot::LabelText::LabelStr(format!("{:?}", n).into_cow())
     }
-    fn edge_label(&'this self, e: &Constraint) -> dot::LabelText<'this> {
+    fn edge_label(&'this self, e: &OutlivesConstraint) -> dot::LabelText<'this> {
         dot::LabelText::LabelStr(format!("{:?}", e.point).into_cow())
     }
 }
 
 impl<'this, 'tcx> dot::GraphWalk<'this> for RegionInferenceContext<'tcx> {
     type Node = RegionVid;
-    type Edge = Constraint;
+    type Edge = OutlivesConstraint;
 
     fn nodes(&'this self) -> dot::Nodes<'this, RegionVid> {
         let vids: Vec<RegionVid> = self.definitions.indices().collect();
         vids.into_cow()
     }
-    fn edges(&'this self) -> dot::Edges<'this, Constraint> {
+    fn edges(&'this self) -> dot::Edges<'this, OutlivesConstraint> {
         (&self.constraints.raw[..]).into_cow()
     }
 
     // Render `a: b` as `a <- b`, indicating the flow
     // of data during inference.
 
-    fn source(&'this self, edge: &Constraint) -> RegionVid {
+    fn source(&'this self, edge: &OutlivesConstraint) -> RegionVid {
         edge.sub
     }
 
-    fn target(&'this self, edge: &Constraint) -> RegionVid {
+    fn target(&'this self, edge: &OutlivesConstraint) -> RegionVid {
         edge.sup
     }
 }
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
index dea2683..0eeacda 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
@@ -68,7 +68,7 @@
     dependency_map: Option<IndexVec<RegionVid, Option<ConstraintIndex>>>,
 
     /// The constraints we have accumulated and used during solving.
-    constraints: IndexVec<ConstraintIndex, Constraint>,
+    constraints: IndexVec<ConstraintIndex, OutlivesConstraint>,
 
     /// Type constraints that we check after solving.
     type_tests: Vec<TypeTest<'tcx>>,
@@ -118,19 +118,19 @@
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct Constraint {
+pub struct OutlivesConstraint {
     // NB. The ordering here is not significant for correctness, but
     // it is for convenience. Before we dump the constraints in the
     // debugging logs, we sort them, and we'd like the "super region"
     // to be first, etc. (In particular, span should remain last.)
     /// The region SUP must outlive SUB...
-    sup: RegionVid,
+    pub sup: RegionVid,
 
     /// Region that must be outlived.
-    sub: RegionVid,
+    pub sub: RegionVid,
 
     /// At this location.
-    point: Location,
+    pub point: Location,
 
     /// Later on, we thread the constraints onto a linked list
     /// grouped by their `sub` field. So if you had:
@@ -140,10 +140,10 @@
     /// 0     | `'a: 'b`   | Some(2)
     /// 1     | `'b: 'c`   | None
     /// 2     | `'c: 'b`   | None
-    next: Option<ConstraintIndex>,
+    pub next: Option<ConstraintIndex>,
 
     /// Where did this constraint arise?
-    span: Span,
+    pub span: Span,
 }
 
 newtype_index!(ConstraintIndex { DEBUG_FORMAT = "ConstraintIndex({})" });
@@ -239,11 +239,19 @@
     /// `num_region_variables` valid inference variables; the first N
     /// of those will be constant regions representing the free
     /// regions defined in `universal_regions`.
+    ///
+    /// The `outlives_constraints` and `type_tests` are an initial set
+    /// of constraints produced by the MIR type check.
     pub(crate) fn new(
         var_infos: VarInfos,
         universal_regions: UniversalRegions<'tcx>,
         mir: &Mir<'tcx>,
+        outlives_constraints: Vec<OutlivesConstraint>,
+        type_tests: Vec<TypeTest<'tcx>>,
     ) -> Self {
+        // The `next` field should not yet have been initialized:
+        debug_assert!(outlives_constraints.iter().all(|c| c.next.is_none()));
+
         let num_region_variables = var_infos.len();
         let num_universal_regions = universal_regions.len();
 
@@ -261,8 +269,8 @@
             liveness_constraints: RegionValues::new(elements, num_region_variables),
             inferred_values: None,
             dependency_map: None,
-            constraints: IndexVec::new(),
-            type_tests: Vec::new(),
+            constraints: IndexVec::from_raw(outlives_constraints),
+            type_tests,
             universal_regions,
         };
 
@@ -345,7 +353,8 @@
     where
         R: ToRegionVid,
     {
-        let inferred_values = self.inferred_values
+        let inferred_values = self
+            .inferred_values
             .as_ref()
             .expect("region values not yet inferred");
         inferred_values.contains(r.to_region_vid(), p)
@@ -353,7 +362,8 @@
 
     /// Returns access to the value of `r` for debugging purposes.
     crate fn region_value_str(&self, r: RegionVid) -> String {
-        let inferred_values = self.inferred_values
+        let inferred_values = self
+            .inferred_values
             .as_ref()
             .expect("region values not yet inferred");
 
@@ -387,7 +397,7 @@
     ) {
         debug!("add_outlives({:?}: {:?} @ {:?}", sup, sub, point);
         assert!(self.inferred_values.is_none(), "values already inferred");
-        self.constraints.push(Constraint {
+        self.constraints.push(OutlivesConstraint {
             span,
             sup,
             sub,
@@ -396,11 +406,6 @@
         });
     }
 
-    /// Add a "type test" that must be satisfied.
-    pub(super) fn add_type_test(&mut self, type_test: TypeTest<'tcx>) {
-        self.type_tests.push(type_test);
-    }
-
     /// Perform region inference and report errors if we see any
     /// unsatisfiable constraints. If this is a closure, returns the
     /// region requirements to propagate to our creator, if any.
@@ -465,7 +470,6 @@
         self.inferred_values = Some(inferred_values);
     }
 
-    #[inline(never)] // ensure dfs is identifiable in profiles
     fn compute_region_values(&self, _mir: &Mir<'tcx>) -> RegionValues {
         debug!("compute_region_values()");
         debug!("compute_region_values: constraints={:#?}", {
@@ -516,7 +520,6 @@
     /// indices of constraints that need to be re-evaluated when X changes.
     /// These are constraints like Y: X @ P -- so if X changed, we may
     /// need to grow Y.
-    #[inline(never)] // ensure dfs is identifiable in profiles
     fn build_dependency_map(&mut self) -> IndexVec<RegionVid, Option<ConstraintIndex>> {
         let mut map = IndexVec::from_elem(None, &self.definitions);
 
@@ -595,7 +598,8 @@
         if self.universal_regions.is_universal_region(r) {
             return self.definitions[r].external_name;
         } else {
-            let inferred_values = self.inferred_values
+            let inferred_values = self
+                .inferred_values
                 .as_ref()
                 .expect("region values not yet inferred");
             let upper_bound = self.universal_upper_bound(r);
@@ -634,8 +638,11 @@
         // region, which ensures it can be encoded in a `ClosureOutlivesRequirement`.
         let lower_bound_plus = self.non_local_universal_upper_bound(*lower_bound);
         assert!(self.universal_regions.is_universal_region(lower_bound_plus));
-        assert!(!self.universal_regions
-            .is_local_free_region(lower_bound_plus));
+        assert!(
+            !self
+                .universal_regions
+                .is_local_free_region(lower_bound_plus)
+        );
 
         propagated_outlives_requirements.push(ClosureOutlivesRequirement {
             subject,
@@ -663,7 +670,8 @@
     ) -> Option<ClosureOutlivesSubject<'gcx>> {
         let tcx = infcx.tcx;
         let gcx = tcx.global_tcx();
-        let inferred_values = self.inferred_values
+        let inferred_values = self
+            .inferred_values
             .as_ref()
             .expect("region values not yet inferred");
 
@@ -844,7 +852,8 @@
             sup_region, sub_region, point
         );
 
-        let inferred_values = self.inferred_values
+        let inferred_values = self
+            .inferred_values
             .as_ref()
             .expect("values for regions not yet inferred");
 
@@ -911,7 +920,8 @@
     ) {
         // The universal regions are always found in a prefix of the
         // full list.
-        let universal_definitions = self.definitions
+        let universal_definitions = self
+            .definitions
             .iter_enumerated()
             .take_while(|(_, fr_definition)| fr_definition.is_universal);
 
@@ -1139,7 +1149,7 @@
     }
 }
 
-impl fmt::Debug for Constraint {
+impl fmt::Debug for OutlivesConstraint {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         write!(
             formatter,
diff --git a/src/librustc_mir/borrow_check/nll/subtype_constraint_generation.rs b/src/librustc_mir/borrow_check/nll/subtype_constraint_generation.rs
deleted file mode 100644
index 9db1908..0000000
--- a/src/librustc_mir/borrow_check/nll/subtype_constraint_generation.rs
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright 2017 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 borrow_check::location::LocationTable;
-use borrow_check::nll::facts::AllFacts;
-use rustc::infer::region_constraints::Constraint;
-use rustc::infer::region_constraints::RegionConstraintData;
-use rustc::infer::region_constraints::{Verify, VerifyBound};
-use rustc::mir::{Location, Mir};
-use rustc::ty;
-use std::iter;
-use syntax::codemap::Span;
-
-use super::region_infer::{RegionInferenceContext, RegionTest, TypeTest};
-use super::type_check::Locations;
-use super::type_check::MirTypeckRegionConstraints;
-use super::type_check::OutlivesSet;
-
-/// When the MIR type-checker executes, it validates all the types in
-/// the MIR, and in the process generates a set of constraints that
-/// must hold regarding the regions in the MIR, along with locations
-/// *where* they must hold. This code takes those constriants and adds
-/// them into the NLL `RegionInferenceContext`.
-pub(super) fn generate<'tcx>(
-    regioncx: &mut RegionInferenceContext<'tcx>,
-    all_facts: &mut Option<AllFacts>,
-    location_table: &LocationTable,
-    mir: &Mir<'tcx>,
-    constraints: &MirTypeckRegionConstraints<'tcx>,
-) {
-    SubtypeConstraintGenerator {
-        regioncx,
-        location_table,
-        mir,
-    }.generate(constraints, all_facts);
-}
-
-struct SubtypeConstraintGenerator<'cx, 'tcx: 'cx> {
-    regioncx: &'cx mut RegionInferenceContext<'tcx>,
-    location_table: &'cx LocationTable,
-    mir: &'cx Mir<'tcx>,
-}
-
-impl<'cx, 'tcx> SubtypeConstraintGenerator<'cx, 'tcx> {
-    fn generate(
-        &mut self,
-        constraints: &MirTypeckRegionConstraints<'tcx>,
-        all_facts: &mut Option<AllFacts>,
-    ) {
-        let MirTypeckRegionConstraints {
-            liveness_set,
-            outlives_sets,
-        } = constraints;
-
-        debug!(
-            "generate(liveness_set={} items, outlives_sets={} items)",
-            liveness_set.len(),
-            outlives_sets.len()
-        );
-
-        for (region, location, cause) in liveness_set {
-            debug!("generate: {:#?} is live at {:#?}", region, location);
-            let region_vid = self.to_region_vid(region);
-            self.regioncx.add_live_point(region_vid, *location, &cause);
-        }
-
-        if let Some(all_facts) = all_facts {
-            all_facts
-                .region_live_at
-                .extend(liveness_set.into_iter().flat_map(|(region, location, _)| {
-                    let r = self.to_region_vid(region);
-                    let p1 = self.location_table.start_index(*location);
-                    let p2 = self.location_table.mid_index(*location);
-                    iter::once((r, p1)).chain(iter::once((r, p2)))
-                }));
-        }
-
-        for OutlivesSet { locations, data } in outlives_sets {
-            debug!("generate: constraints at: {:#?}", locations);
-            let RegionConstraintData {
-                constraints,
-                verifys,
-                givens,
-            } = data;
-
-            let span = self.mir
-                .source_info(locations.from_location().unwrap_or(Location::START))
-                .span;
-
-            let at_location = locations.at_location().unwrap_or(Location::START);
-
-            for constraint in constraints.keys() {
-                debug!("generate: constraint: {:?}", constraint);
-                let (a_vid, b_vid) = match constraint {
-                    Constraint::VarSubVar(a_vid, b_vid) => (*a_vid, *b_vid),
-                    Constraint::RegSubVar(a_r, b_vid) => (self.to_region_vid(a_r), *b_vid),
-                    Constraint::VarSubReg(a_vid, b_r) => (*a_vid, self.to_region_vid(b_r)),
-                    Constraint::RegSubReg(a_r, b_r) => {
-                        (self.to_region_vid(a_r), self.to_region_vid(b_r))
-                    }
-                };
-
-                // We have the constraint that `a_vid <= b_vid`. Add
-                // `b_vid: a_vid` to our region checker. Note that we
-                // reverse direction, because `regioncx` talks about
-                // "outlives" (`>=`) whereas the region constraints
-                // talk about `<=`.
-                self.regioncx.add_outlives(span, b_vid, a_vid, at_location);
-
-                // In the new analysis, all outlives relations etc
-                // "take effect" at the mid point of the statement
-                // that requires them, so ignore the `at_location`.
-                if let Some(all_facts) = all_facts {
-                    if let Some(from_location) = locations.from_location() {
-                        all_facts.outlives.push((
-                            b_vid,
-                            a_vid,
-                            self.location_table.mid_index(from_location),
-                        ));
-                    } else {
-                        for location in self.location_table.all_points() {
-                            all_facts.outlives.push((b_vid, a_vid, location));
-                        }
-                    }
-                }
-            }
-
-            for verify in verifys {
-                let type_test = self.verify_to_type_test(verify, span, locations);
-                self.regioncx.add_type_test(type_test);
-            }
-
-            assert!(
-                givens.is_empty(),
-                "MIR type-checker does not use givens (thank goodness)"
-            );
-        }
-    }
-
-    fn verify_to_type_test(
-        &self,
-        verify: &Verify<'tcx>,
-        span: Span,
-        locations: &Locations,
-    ) -> TypeTest<'tcx> {
-        let generic_kind = verify.kind;
-
-        let lower_bound = self.to_region_vid(verify.region);
-
-        let point = locations.at_location().unwrap_or(Location::START);
-
-        let test = self.verify_bound_to_region_test(&verify.bound);
-
-        TypeTest {
-            generic_kind,
-            lower_bound,
-            point,
-            span,
-            test,
-        }
-    }
-
-    fn verify_bound_to_region_test(&self, verify_bound: &VerifyBound<'tcx>) -> RegionTest {
-        match verify_bound {
-            VerifyBound::AnyRegion(regions) => RegionTest::IsOutlivedByAnyRegionIn(
-                regions.iter().map(|r| self.to_region_vid(r)).collect(),
-            ),
-
-            VerifyBound::AllRegions(regions) => RegionTest::IsOutlivedByAllRegionsIn(
-                regions.iter().map(|r| self.to_region_vid(r)).collect(),
-            ),
-
-            VerifyBound::AnyBound(bounds) => RegionTest::Any(
-                bounds
-                    .iter()
-                    .map(|b| self.verify_bound_to_region_test(b))
-                    .collect(),
-            ),
-
-            VerifyBound::AllBounds(bounds) => RegionTest::All(
-                bounds
-                    .iter()
-                    .map(|b| self.verify_bound_to_region_test(b))
-                    .collect(),
-            ),
-        }
-    }
-
-    fn to_region_vid(&self, r: ty::Region<'tcx>) -> ty::RegionVid {
-        self.regioncx.to_region_vid(r)
-    }
-}
diff --git a/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs b/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs
new file mode 100644
index 0000000..06aaf68
--- /dev/null
+++ b/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs
@@ -0,0 +1,190 @@
+// Copyright 2017 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 borrow_check::location::LocationTable;
+use borrow_check::nll::facts::AllFacts;
+use borrow_check::nll::region_infer::{OutlivesConstraint, RegionTest, TypeTest};
+use borrow_check::nll::type_check::Locations;
+use borrow_check::nll::universal_regions::UniversalRegions;
+use rustc::infer::region_constraints::Constraint;
+use rustc::infer::region_constraints::RegionConstraintData;
+use rustc::infer::region_constraints::{Verify, VerifyBound};
+use rustc::mir::{Location, Mir};
+use rustc::ty;
+use syntax::codemap::Span;
+
+crate struct ConstraintConversion<'a, 'tcx: 'a> {
+    mir: &'a Mir<'tcx>,
+    universal_regions: &'a UniversalRegions<'tcx>,
+    location_table: &'a LocationTable,
+    outlives_constraints: &'a mut Vec<OutlivesConstraint>,
+    type_tests: &'a mut Vec<TypeTest<'tcx>>,
+    all_facts: &'a mut Option<AllFacts>,
+
+}
+
+impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
+    crate fn new(
+        mir: &'a Mir<'tcx>,
+        universal_regions: &'a UniversalRegions<'tcx>,
+        location_table: &'a LocationTable,
+        outlives_constraints: &'a mut Vec<OutlivesConstraint>,
+        type_tests: &'a mut Vec<TypeTest<'tcx>>,
+        all_facts: &'a mut Option<AllFacts>,
+    ) -> Self {
+        Self {
+            mir,
+            universal_regions,
+            location_table,
+            outlives_constraints,
+            type_tests,
+            all_facts,
+        }
+    }
+
+    crate fn convert(
+        &mut self,
+        locations: Locations,
+        data: &RegionConstraintData<'tcx>,
+    ) {
+        debug!("generate: constraints at: {:#?}", locations);
+        let RegionConstraintData {
+            constraints,
+            verifys,
+            givens,
+        } = data;
+
+        let span = self
+            .mir
+            .source_info(locations.from_location().unwrap_or(Location::START))
+            .span;
+
+        let at_location = locations.at_location().unwrap_or(Location::START);
+
+        for constraint in constraints.keys() {
+            debug!("generate: constraint: {:?}", constraint);
+            let (a_vid, b_vid) = match constraint {
+                Constraint::VarSubVar(a_vid, b_vid) => (*a_vid, *b_vid),
+                Constraint::RegSubVar(a_r, b_vid) => (self.to_region_vid(a_r), *b_vid),
+                Constraint::VarSubReg(a_vid, b_r) => (*a_vid, self.to_region_vid(b_r)),
+                Constraint::RegSubReg(a_r, b_r) => {
+                    (self.to_region_vid(a_r), self.to_region_vid(b_r))
+                }
+            };
+
+            // We have the constraint that `a_vid <= b_vid`. Add
+            // `b_vid: a_vid` to our region checker. Note that we
+            // reverse direction, because `regioncx` talks about
+            // "outlives" (`>=`) whereas the region constraints
+            // talk about `<=`.
+            self.add_outlives(span, b_vid, a_vid, at_location);
+
+            // In the new analysis, all outlives relations etc
+            // "take effect" at the mid point of the statement
+            // that requires them, so ignore the `at_location`.
+            if let Some(all_facts) = &mut self.all_facts {
+                if let Some(from_location) = locations.from_location() {
+                    all_facts.outlives.push((
+                        b_vid,
+                        a_vid,
+                        self.location_table.mid_index(from_location),
+                    ));
+                } else {
+                    for location in self.location_table.all_points() {
+                        all_facts.outlives.push((b_vid, a_vid, location));
+                    }
+                }
+            }
+        }
+
+        for verify in verifys {
+            let type_test = self.verify_to_type_test(verify, span, locations);
+            self.add_type_test(type_test);
+        }
+
+        assert!(
+            givens.is_empty(),
+            "MIR type-checker does not use givens (thank goodness)"
+        );
+    }
+
+    fn verify_to_type_test(
+        &self,
+        verify: &Verify<'tcx>,
+        span: Span,
+        locations: Locations,
+    ) -> TypeTest<'tcx> {
+        let generic_kind = verify.kind;
+
+        let lower_bound = self.to_region_vid(verify.region);
+
+        let point = locations.at_location().unwrap_or(Location::START);
+
+        let test = self.verify_bound_to_region_test(&verify.bound);
+
+        TypeTest {
+            generic_kind,
+            lower_bound,
+            point,
+            span,
+            test,
+        }
+    }
+
+    fn verify_bound_to_region_test(&self, verify_bound: &VerifyBound<'tcx>) -> RegionTest {
+        match verify_bound {
+            VerifyBound::AnyRegion(regions) => RegionTest::IsOutlivedByAnyRegionIn(
+                regions.iter().map(|r| self.to_region_vid(r)).collect(),
+            ),
+
+            VerifyBound::AllRegions(regions) => RegionTest::IsOutlivedByAllRegionsIn(
+                regions.iter().map(|r| self.to_region_vid(r)).collect(),
+            ),
+
+            VerifyBound::AnyBound(bounds) => RegionTest::Any(
+                bounds
+                    .iter()
+                    .map(|b| self.verify_bound_to_region_test(b))
+                    .collect(),
+            ),
+
+            VerifyBound::AllBounds(bounds) => RegionTest::All(
+                bounds
+                    .iter()
+                    .map(|b| self.verify_bound_to_region_test(b))
+                    .collect(),
+            ),
+        }
+    }
+
+    fn to_region_vid(&self, r: ty::Region<'tcx>) -> ty::RegionVid {
+        self.universal_regions.to_region_vid(r)
+    }
+
+    fn add_outlives(
+        &mut self,
+        span: Span,
+        sup: ty::RegionVid,
+        sub: ty::RegionVid,
+        point: Location,
+    ) {
+        self.outlives_constraints.push(OutlivesConstraint {
+            span,
+            sub,
+            sup,
+            point,
+            next: None,
+        });
+    }
+
+    fn add_type_test(&mut self, type_test: TypeTest<'tcx>) {
+        self.type_tests.push(type_test);
+    }
+}
diff --git a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs
index 2b1878c..d44eed6 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs
@@ -21,11 +21,11 @@
 use borrow_check::nll::universal_regions::UniversalRegions;
 use rustc::hir::def_id::DefId;
 use rustc::infer::InferOk;
-use rustc::ty::Ty;
-use rustc::ty::subst::Subst;
-use rustc::mir::*;
 use rustc::mir::visit::TyContext;
-use rustc::traits::PredicateObligations;
+use rustc::mir::*;
+use rustc::traits::{ObligationCause, PredicateObligations};
+use rustc::ty::subst::Subst;
+use rustc::ty::Ty;
 
 use rustc_data_structures::indexed_vec::Idx;
 
@@ -56,8 +56,8 @@
         }
 
         assert!(
-            mir.yield_ty.is_some() && universal_regions.yield_ty.is_some() ||
-            mir.yield_ty.is_none() && universal_regions.yield_ty.is_none()
+            mir.yield_ty.is_some() && universal_regions.yield_ty.is_some()
+                || mir.yield_ty.is_none() && universal_regions.yield_ty.is_none()
         );
         if let Some(mir_yield_ty) = mir.yield_ty {
             let ur_yield_ty = universal_regions.yield_ty.unwrap();
@@ -76,57 +76,67 @@
             output_ty
         );
         let mir_output_ty = mir.local_decls[RETURN_PLACE].ty;
-        let anon_type_map = self.fully_perform_op(Locations::All, |cx| {
-            let mut obligations = ObligationAccumulator::default();
+        let anon_type_map =
+            self.fully_perform_op(
+                Locations::All,
+                || format!("input_output"),
+                |cx| {
+                    let mut obligations = ObligationAccumulator::default();
 
-            let (output_ty, anon_type_map) = obligations.add(infcx.instantiate_anon_types(
-                mir_def_id,
-                cx.body_id,
-                cx.param_env,
-                &output_ty,
-            ));
-            debug!(
-                "equate_inputs_and_outputs: instantiated output_ty={:?}",
-                output_ty
-            );
-            debug!(
-                "equate_inputs_and_outputs: anon_type_map={:#?}",
-                anon_type_map
-            );
+                    let dummy_body_id = ObligationCause::dummy().body_id;
+                    let (output_ty, anon_type_map) = obligations.add(infcx.instantiate_anon_types(
+                        mir_def_id,
+                        dummy_body_id,
+                        cx.param_env,
+                        &output_ty,
+                    ));
+                    debug!(
+                        "equate_inputs_and_outputs: instantiated output_ty={:?}",
+                        output_ty
+                    );
+                    debug!(
+                        "equate_inputs_and_outputs: anon_type_map={:#?}",
+                        anon_type_map
+                    );
 
-            debug!(
-                "equate_inputs_and_outputs: mir_output_ty={:?}",
-                mir_output_ty
-            );
-            obligations.add(infcx
-                .at(&cx.misc(cx.last_span), cx.param_env)
-                .eq(output_ty, mir_output_ty)?);
+                    debug!(
+                        "equate_inputs_and_outputs: mir_output_ty={:?}",
+                        mir_output_ty
+                    );
+                    obligations.add(
+                        infcx
+                            .at(&ObligationCause::dummy(), cx.param_env)
+                            .eq(output_ty, mir_output_ty)?,
+                    );
 
-            for (&anon_def_id, anon_decl) in &anon_type_map {
-                let anon_defn_ty = tcx.type_of(anon_def_id);
-                let anon_defn_ty = anon_defn_ty.subst(tcx, anon_decl.substs);
-                let anon_defn_ty = renumber::renumber_regions(
-                    cx.infcx,
-                    TyContext::Location(Location::START),
-                    &anon_defn_ty,
-                );
-                debug!(
-                    "equate_inputs_and_outputs: concrete_ty={:?}",
-                    anon_decl.concrete_ty
-                );
-                debug!("equate_inputs_and_outputs: anon_defn_ty={:?}", anon_defn_ty);
-                obligations.add(infcx
-                    .at(&cx.misc(cx.last_span), cx.param_env)
-                    .eq(anon_decl.concrete_ty, anon_defn_ty)?);
-            }
+                    for (&anon_def_id, anon_decl) in &anon_type_map {
+                        let anon_defn_ty = tcx.type_of(anon_def_id);
+                        let anon_defn_ty = anon_defn_ty.subst(tcx, anon_decl.substs);
+                        let anon_defn_ty = renumber::renumber_regions(
+                            cx.infcx,
+                            TyContext::Location(Location::START),
+                            &anon_defn_ty,
+                        );
+                        debug!(
+                            "equate_inputs_and_outputs: concrete_ty={:?}",
+                            anon_decl.concrete_ty
+                        );
+                        debug!("equate_inputs_and_outputs: anon_defn_ty={:?}", anon_defn_ty);
+                        obligations.add(
+                            infcx
+                                .at(&ObligationCause::dummy(), cx.param_env)
+                                .eq(anon_decl.concrete_ty, anon_defn_ty)?,
+                        );
+                    }
 
-            debug!("equate_inputs_and_outputs: equated");
+                    debug!("equate_inputs_and_outputs: equated");
 
-            Ok(InferOk {
-                value: Some(anon_type_map),
-                obligations: obligations.into_vec(),
-            })
-        }).unwrap_or_else(|terr| {
+                    Ok(InferOk {
+                        value: Some(anon_type_map),
+                        obligations: obligations.into_vec(),
+                    })
+                },
+            ).unwrap_or_else(|terr| {
                 span_mirbug!(
                     self,
                     Location::START,
@@ -143,13 +153,17 @@
         // prove that `T: Iterator` where `T` is the type we
         // instantiated it with).
         if let Some(anon_type_map) = anon_type_map {
-            self.fully_perform_op(Locations::All, |_cx| {
-                infcx.constrain_anon_types(&anon_type_map, universal_regions);
-                Ok(InferOk {
-                    value: (),
-                    obligations: vec![],
-                })
-            }).unwrap();
+            self.fully_perform_op(
+                Locations::All,
+                || format!("anon_type_map"),
+                |_cx| {
+                    infcx.constrain_anon_types(&anon_type_map, universal_regions);
+                    Ok(InferOk {
+                        value: (),
+                        obligations: vec![],
+                    })
+                },
+            ).unwrap();
         }
     }
 
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness.rs
index d19fd2b..80f5fe4 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness.rs
@@ -8,15 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use dataflow::{FlowAtLocation, FlowsAtLocation};
 use borrow_check::nll::region_infer::Cause;
-use dataflow::MaybeInitializedPlaces;
-use dataflow::move_paths::{HasMoveData, MoveData};
-use rustc::mir::{BasicBlock, Location, Mir};
-use rustc::mir::Local;
-use rustc::ty::{Ty, TyCtxt, TypeFoldable};
-use rustc::infer::InferOk;
 use borrow_check::nll::type_check::AtLocation;
+use dataflow::move_paths::{HasMoveData, MoveData};
+use dataflow::MaybeInitializedPlaces;
+use dataflow::{FlowAtLocation, FlowsAtLocation};
+use rustc::infer::region_constraints::RegionConstraintData;
+use rustc::mir::Local;
+use rustc::mir::{BasicBlock, Location, Mir};
+use rustc::traits::ObligationCause;
+use rustc::ty::subst::Kind;
+use rustc::ty::{Ty, TypeFoldable};
+use rustc_data_structures::fx::FxHashMap;
+use std::rc::Rc;
 use util::liveness::LivenessResults;
 
 use super::TypeChecker;
@@ -36,14 +40,13 @@
     flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
     move_data: &MoveData<'tcx>,
 ) {
-    let tcx = cx.tcx();
     let mut generator = TypeLivenessGenerator {
         cx,
-        tcx,
         mir,
         liveness,
         flow_inits,
         move_data,
+        drop_data: FxHashMap(),
     };
 
     for bb in mir.basic_blocks().indices() {
@@ -59,11 +62,16 @@
     'gcx: 'tcx,
 {
     cx: &'gen mut TypeChecker<'typeck, 'gcx, 'tcx>,
-    tcx: TyCtxt<'typeck, 'gcx, 'tcx>,
     mir: &'gen Mir<'tcx>,
     liveness: &'gen LivenessResults,
     flow_inits: &'gen mut FlowAtLocation<MaybeInitializedPlaces<'flow, 'gcx, 'tcx>>,
     move_data: &'gen MoveData<'tcx>,
+    drop_data: FxHashMap<Ty<'tcx>, DropData<'tcx>>,
+}
+
+struct DropData<'tcx> {
+    dropped_kinds: Vec<Kind<'tcx>>,
+    region_constraint_data: Option<Rc<RegionConstraintData<'tcx>>>,
 }
 
 impl<'gen, 'typeck, 'flow, 'gcx, 'tcx> TypeLivenessGenerator<'gen, 'typeck, 'flow, 'gcx, 'tcx> {
@@ -80,7 +88,7 @@
                 for live_local in live_locals.iter() {
                     let live_local_ty = self.mir.local_decls[live_local].ty;
                     let cause = Cause::LiveVar(live_local, location);
-                    self.push_type_live_constraint(live_local_ty, location, cause);
+                    Self::push_type_live_constraint(&mut self.cx, live_local_ty, location, cause);
                 }
             });
 
@@ -104,13 +112,15 @@
                     location, live_local
                 );
 
-                self.flow_inits.each_state_bit(|mpi_init| {
-                    debug!(
-                        "add_liveness_constraints: location={:?} initialized={:?}",
-                        location,
-                        &self.flow_inits.operator().move_data().move_paths[mpi_init]
-                    );
-                });
+                if log_enabled!(::log::Level::Debug) {
+                    self.flow_inits.each_state_bit(|mpi_init| {
+                        debug!(
+                            "add_liveness_constraints: location={:?} initialized={:?}",
+                            location,
+                            &self.flow_inits.operator().move_data().move_paths[mpi_init]
+                        );
+                    });
+                }
 
                 let mpi = self.move_data.rev_lookup.find_local(live_local);
                 if let Some(initialized_child) = self.flow_inits.has_any_child_of(mpi) {
@@ -146,8 +156,12 @@
     /// `location` -- i.e., it may be used later. This means that all
     /// regions appearing in the type `live_ty` must be live at
     /// `location`.
-    fn push_type_live_constraint<T>(&mut self, value: T, location: Location, cause: Cause)
-    where
+    fn push_type_live_constraint<T>(
+        cx: &mut TypeChecker<'_, 'gcx, 'tcx>,
+        value: T,
+        location: Location,
+        cause: Cause,
+    ) where
         T: TypeFoldable<'tcx>,
     {
         debug!(
@@ -155,8 +169,8 @@
             value, location
         );
 
-        self.tcx.for_each_free_region(&value, |live_region| {
-            self.cx
+        cx.tcx().for_each_free_region(&value, |live_region| {
+            cx
                 .constraints
                 .liveness_set
                 .push((live_region, location, cause.clone()));
@@ -179,47 +193,44 @@
             dropped_local, dropped_ty, location
         );
 
-        // If we end visiting the same type twice (usually due to a cycle involving
-        // associated types), we need to ensure that its region types match up with the type
-        // we added to the 'known' map the first time around. For this reason, we need
-        // our infcx to hold onto its calculated region constraints after each call
-        // to dtorck_constraint_for_ty. Otherwise, normalizing the corresponding associated
-        // type will end up instantiating the type with a new set of inference variables
-        // Since this new type will never be in 'known', we end up looping forever.
-        //
-        // For this reason, we avoid calling TypeChecker.normalize, instead doing all normalization
-        // ourselves in one large 'fully_perform_op' callback.
-        let kind_constraints = self.cx
-            .fully_perform_op(location.at_self(), |cx| {
-                let span = cx.last_span;
+        let drop_data = self.drop_data.entry(dropped_ty).or_insert_with({
+            let cx = &mut self.cx;
+            move || Self::compute_drop_data(cx, dropped_ty)
+        });
 
-                let mut final_obligations = Vec::new();
-                let mut kind_constraints = Vec::new();
+        if let Some(data) = &drop_data.region_constraint_data {
+            self.cx
+                .push_region_constraints(location.at_self(), data.clone());
+        }
 
-                let InferOk {
-                    value: kinds,
-                    obligations,
-                } = cx.infcx
-                    .at(&cx.misc(span), cx.param_env)
-                    .dropck_outlives(dropped_ty);
-                for kind in kinds {
-                    // All things in the `outlives` array may be touched by
-                    // the destructor and must be live at this point.
-                    let cause = Cause::DropVar(dropped_local, location);
-                    kind_constraints.push((kind, location, cause));
-                }
+        // All things in the `outlives` array may be touched by
+        // the destructor and must be live at this point.
+        let cause = Cause::DropVar(dropped_local, location);
+        for &kind in &drop_data.dropped_kinds {
+            Self::push_type_live_constraint(&mut self.cx, kind, location, cause);
+        }
+    }
 
-                final_obligations.extend(obligations);
+    fn compute_drop_data(
+        cx: &mut TypeChecker<'_, 'gcx, 'tcx>,
+        dropped_ty: Ty<'tcx>,
+    ) -> DropData<'tcx> {
+        debug!("compute_drop_data(dropped_ty={:?})", dropped_ty,);
 
-                Ok(InferOk {
-                    value: kind_constraints,
-                    obligations: final_obligations,
-                })
-            })
-            .unwrap();
+        let (dropped_kinds, region_constraint_data) =
+            cx.fully_perform_op_and_get_region_constraint_data(
+                || format!("compute_drop_data(dropped_ty={:?})", dropped_ty),
+                |cx| {
+                    Ok(cx
+                        .infcx
+                        .at(&ObligationCause::dummy(), cx.param_env)
+                        .dropck_outlives(dropped_ty))
+                },
+            ).unwrap();
 
-        for (kind, location, cause) in kind_constraints {
-            self.push_type_live_constraint(kind, location, cause);
+        DropData {
+            dropped_kinds,
+            region_constraint_data,
         }
     }
 }
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 04f5024..d25cec7 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -11,8 +11,10 @@
 //! This pass type-checks the MIR to ensure it is not broken.
 #![allow(unreachable_code)]
 
+use borrow_check::location::LocationTable;
+use borrow_check::nll::facts::AllFacts;
 use borrow_check::nll::region_infer::Cause;
-use borrow_check::nll::region_infer::ClosureRegionRequirementsExt;
+use borrow_check::nll::region_infer::{ClosureRegionRequirementsExt, OutlivesConstraint, TypeTest};
 use borrow_check::nll::universal_regions::UniversalRegions;
 use dataflow::move_paths::MoveData;
 use dataflow::FlowAtLocation;
@@ -20,17 +22,17 @@
 use rustc::hir::def_id::DefId;
 use rustc::infer::region_constraints::{GenericKind, RegionConstraintData};
 use rustc::infer::{InferCtxt, InferOk, InferResult, LateBoundRegionConversionTime, UnitResult};
+use rustc::mir::interpret::EvalErrorKind::BoundsCheck;
 use rustc::mir::tcx::PlaceTy;
 use rustc::mir::visit::{PlaceContext, Visitor};
-use rustc::mir::interpret::EvalErrorKind::BoundsCheck;
 use rustc::mir::*;
 use rustc::traits::query::NoSolution;
-use rustc::traits::{self, Normalized, TraitEngine};
+use rustc::traits::{self, ObligationCause, Normalized, TraitEngine};
 use rustc::ty::error::TypeError;
 use rustc::ty::fold::TypeFoldable;
 use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeVariants};
 use std::fmt;
-use syntax::ast;
+use std::rc::Rc;
 use syntax_pos::{Span, DUMMY_SP};
 use transform::{MirPass, MirSource};
 use util::liveness::LivenessResults;
@@ -45,7 +47,7 @@
             $context.last_span,
             &format!(
                 "broken MIR in {:?} ({:?}): {}",
-                $context.body_id,
+                $context.mir_def_id,
                 $elem,
                 format_args!($($message)*),
             ),
@@ -62,6 +64,7 @@
     })
 }
 
+mod constraint_conversion;
 mod input_output;
 mod liveness;
 
@@ -100,19 +103,25 @@
     mir: &Mir<'tcx>,
     mir_def_id: DefId,
     universal_regions: &UniversalRegions<'tcx>,
+    location_table: &LocationTable,
     liveness: &LivenessResults,
+    all_facts: &mut Option<AllFacts>,
     flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
     move_data: &MoveData<'tcx>,
 ) -> MirTypeckRegionConstraints<'tcx> {
-    let body_id = infcx.tcx.hir.as_local_node_id(mir_def_id).unwrap();
     let implicit_region_bound = infcx.tcx.mk_region(ty::ReVar(universal_regions.fr_fn_body));
     type_check_internal(
         infcx,
-        body_id,
+        mir_def_id,
         param_env,
         mir,
         &universal_regions.region_bound_pairs,
         Some(implicit_region_bound),
+        Some(BorrowCheckContext {
+            universal_regions,
+            location_table,
+            all_facts,
+        }),
         &mut |cx| {
             liveness::generate(cx, mir, liveness, flow_inits, move_data);
 
@@ -123,19 +132,22 @@
 
 fn type_check_internal<'gcx, 'tcx>(
     infcx: &InferCtxt<'_, 'gcx, 'tcx>,
-    body_id: ast::NodeId,
+    mir_def_id: DefId,
     param_env: ty::ParamEnv<'gcx>,
     mir: &Mir<'tcx>,
     region_bound_pairs: &[(ty::Region<'tcx>, GenericKind<'tcx>)],
     implicit_region_bound: Option<ty::Region<'tcx>>,
+    borrowck_context: Option<BorrowCheckContext<'_, 'tcx>>,
     extra: &mut dyn FnMut(&mut TypeChecker<'_, 'gcx, 'tcx>),
 ) -> MirTypeckRegionConstraints<'tcx> {
     let mut checker = TypeChecker::new(
         infcx,
-        body_id,
+        mir_def_id,
         param_env,
         region_bound_pairs,
         implicit_region_bound,
+        borrowck_context,
+        mir,
     );
     let errors_reported = {
         let mut verifier = TypeVerifier::new(&mut checker, mir);
@@ -173,7 +185,7 @@
     cx: &'a mut TypeChecker<'b, 'gcx, 'tcx>,
     mir: &'a Mir<'tcx>,
     last_span: Span,
-    body_id: ast::NodeId,
+    mir_def_id: DefId,
     errors_reported: bool,
 }
 
@@ -221,7 +233,7 @@
     fn new(cx: &'a mut TypeChecker<'b, 'gcx, 'tcx>, mir: &'a Mir<'tcx>) -> Self {
         TypeVerifier {
             mir,
-            body_id: cx.body_id,
+            mir_def_id: cx.mir_def_id,
             cx,
             last_span: mir.span,
             errors_reported: false,
@@ -300,7 +312,8 @@
 
         debug!("sanitize_constant: expected_ty={:?}", expected_ty);
 
-        if let Err(terr) = self.cx
+        if let Err(terr) = self
+            .cx
             .eq_types(expected_ty, constant.ty, location.at_self())
         {
             span_mirbug!(
@@ -580,17 +593,25 @@
     infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
     param_env: ty::ParamEnv<'gcx>,
     last_span: Span,
-    body_id: ast::NodeId,
+    mir_def_id: DefId,
     region_bound_pairs: &'a [(ty::Region<'tcx>, GenericKind<'tcx>)],
     implicit_region_bound: Option<ty::Region<'tcx>>,
     reported_errors: FxHashSet<(Ty<'tcx>, Span)>,
     constraints: MirTypeckRegionConstraints<'tcx>,
+    borrowck_context: Option<BorrowCheckContext<'a, 'tcx>>,
+    mir: &'a Mir<'tcx>,
+}
+
+struct BorrowCheckContext<'a, 'tcx: 'a> {
+    universal_regions: &'a UniversalRegions<'tcx>,
+    location_table: &'a LocationTable,
+    all_facts: &'a mut Option<AllFacts>,
 }
 
 /// A collection of region constraints that must be satisfied for the
 /// program to be considered well-typed.
 #[derive(Default)]
-pub(crate) struct MirTypeckRegionConstraints<'tcx> {
+crate struct MirTypeckRegionConstraints<'tcx> {
     /// In general, the type-checker is not responsible for enforcing
     /// liveness constraints; this job falls to the region inferencer,
     /// which performs a liveness analysis. However, in some limited
@@ -598,24 +619,11 @@
     /// not otherwise appear in the MIR -- in particular, the
     /// late-bound regions that it instantiates at call-sites -- and
     /// hence it must report on their liveness constraints.
-    pub liveness_set: Vec<(ty::Region<'tcx>, Location, Cause)>,
+    crate liveness_set: Vec<(ty::Region<'tcx>, Location, Cause)>,
 
-    /// During the course of type-checking, we will accumulate region
-    /// constraints due to performing subtyping operations or solving
-    /// traits. These are accumulated into this vector for later use.
-    pub outlives_sets: Vec<OutlivesSet<'tcx>>,
-}
+    crate outlives_constraints: Vec<OutlivesConstraint>,
 
-/// Outlives relationships between regions and types created at a
-/// particular point within the control-flow graph.
-pub struct OutlivesSet<'tcx> {
-    /// The locations associated with these constraints.
-    pub locations: Locations,
-
-    /// Constraints generated. In terms of the NLL RFC, when you have
-    /// a constraint `R1: R2 @ P`, the data in there specifies things
-    /// like `R1: R2`.
-    pub data: RegionConstraintData<'tcx>,
+    crate type_tests: Vec<TypeTest<'tcx>>,
 }
 
 /// The `Locations` type summarizes *where* region constraints are
@@ -667,7 +675,7 @@
         /// NLL RFC, when you have a constraint `R1: R2 @ P`, this field
         /// is the `P` value.
         at_location: Location,
-    }
+    },
 }
 
 impl Locations {
@@ -689,37 +697,99 @@
 impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
     fn new(
         infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
-        body_id: ast::NodeId,
+        mir_def_id: DefId,
         param_env: ty::ParamEnv<'gcx>,
         region_bound_pairs: &'a [(ty::Region<'tcx>, GenericKind<'tcx>)],
         implicit_region_bound: Option<ty::Region<'tcx>>,
+        borrowck_context: Option<BorrowCheckContext<'a, 'tcx>>,
+        mir: &'a Mir<'tcx>,
     ) -> Self {
         TypeChecker {
             infcx,
             last_span: DUMMY_SP,
-            body_id,
+            mir_def_id,
             param_env,
             region_bound_pairs,
             implicit_region_bound,
+            borrowck_context,
+            mir,
             reported_errors: FxHashSet(),
             constraints: MirTypeckRegionConstraints::default(),
         }
     }
 
-    fn misc(&self, span: Span) -> traits::ObligationCause<'tcx> {
-        traits::ObligationCause::misc(span, self.body_id)
-    }
-
-    fn fully_perform_op<OP, R>(
+    /// Given some operation `op` that manipulates types, proves
+    /// predicates, or otherwise uses the inference context, executes
+    /// `op` and then executes all the further obligations that `op`
+    /// returns. This will yield a set of outlives constraints amongst
+    /// regions which are extracted and stored as having occured at
+    /// `locations`.
+    ///
+    /// **Any `rustc::infer` operations that might generate region
+    /// constraints should occur within this method so that those
+    /// constraints can be properly localized!**
+    fn fully_perform_op<R>(
         &mut self,
         locations: Locations,
-        op: OP,
-    ) -> Result<R, TypeError<'tcx>>
-    where
-        OP: FnOnce(&mut Self) -> InferResult<'tcx, R>,
-    {
+        describe_op: impl Fn() -> String,
+        op: impl FnOnce(&mut Self) -> InferResult<'tcx, R>,
+    ) -> Result<R, TypeError<'tcx>> {
+        let (r, opt_data) = self.fully_perform_op_and_get_region_constraint_data(
+            || format!("{} at {:?}", describe_op(), locations),
+            op,
+        )?;
+
+        if let Some(data) = opt_data {
+            self.push_region_constraints(locations, data);
+        }
+
+        Ok(r)
+    }
+
+    fn push_region_constraints(
+        &mut self,
+        locations: Locations,
+        data: Rc<RegionConstraintData<'tcx>>,
+    ) {
+        debug!(
+            "push_region_constraints: constraints generated at {:?} are {:#?}",
+            locations, data
+        );
+
+        if let Some(borrowck_context) = &mut self.borrowck_context {
+            constraint_conversion::ConstraintConversion::new(
+                self.mir,
+                borrowck_context.universal_regions,
+                borrowck_context.location_table,
+                &mut self.constraints.outlives_constraints,
+                &mut self.constraints.type_tests,
+                &mut borrowck_context.all_facts,
+            ).convert(locations, &data);
+        }
+    }
+
+    /// Helper for `fully_perform_op`, but also used on its own
+    /// sometimes to enable better caching: executes `op` fully (along
+    /// with resulting obligations) and returns the full set of region
+    /// obligations. If the same `op` were to be performed at some
+    /// other location, then the same set of region obligations would
+    /// be generated there, so this can be useful for caching.
+    fn fully_perform_op_and_get_region_constraint_data<R>(
+        &mut self,
+        describe_op: impl Fn() -> String,
+        op: impl FnOnce(&mut Self) -> InferResult<'tcx, R>,
+    ) -> Result<(R, Option<Rc<RegionConstraintData<'tcx>>>), TypeError<'tcx>> {
+        if cfg!(debug_assertions) {
+            info!(
+                "fully_perform_op_and_get_region_constraint_data({})",
+                describe_op(),
+            );
+        }
+
         let mut fulfill_cx = TraitEngine::new(self.infcx.tcx);
+        let dummy_body_id = ObligationCause::dummy().body_id;
         let InferOk { value, obligations } = self.infcx.commit_if_ok(|_| op(self))?;
+        debug_assert!(obligations.iter().all(|o| o.cause.body_id == dummy_body_id));
         fulfill_cx.register_predicate_obligations(self.infcx, obligations);
         if let Err(e) = fulfill_cx.select_all_or_error(self.infcx) {
             span_mirbug!(self, "", "errors selecting obligation: {:?}", e);
@@ -729,21 +799,15 @@
             self.region_bound_pairs,
             self.implicit_region_bound,
             self.param_env,
-            self.body_id,
+            dummy_body_id,
         );
 
         let data = self.infcx.take_and_reset_region_constraints();
-        if !data.is_empty() {
-            debug!(
-                "fully_perform_op: constraints generated at {:?} are {:#?}",
-                locations, data
-            );
-            self.constraints
-                .outlives_sets
-                .push(OutlivesSet { locations, data });
+        if data.is_empty() {
+            Ok((value, None))
+        } else {
+            Ok((value, Some(Rc::new(data))))
         }
-
-        Ok(value)
     }
 
     fn sub_types(
@@ -752,19 +816,37 @@
         sup: Ty<'tcx>,
         locations: Locations,
     ) -> UnitResult<'tcx> {
-        self.fully_perform_op(locations, |this| {
-            this.infcx
-                .at(&this.misc(this.last_span), this.param_env)
-                .sup(sup, sub)
-        })
+        // Micro-optimization.
+        if sub == sup {
+            return Ok(());
+        }
+
+        self.fully_perform_op(
+            locations,
+            || format!("sub_types({:?} <: {:?})", sub, sup),
+            |this| {
+                this.infcx
+                    .at(&ObligationCause::dummy(), this.param_env)
+                    .sup(sup, sub)
+            },
+        )
     }
 
     fn eq_types(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, locations: Locations) -> UnitResult<'tcx> {
-        self.fully_perform_op(locations, |this| {
-            this.infcx
-                .at(&this.misc(this.last_span), this.param_env)
-                .eq(b, a)
-        })
+        // Micro-optimization.
+        if a == b {
+            return Ok(());
+        }
+
+        self.fully_perform_op(
+            locations,
+            || format!("eq_types({:?} = {:?})", a, b),
+            |this| {
+                this.infcx
+                    .at(&ObligationCause::dummy(), this.param_env)
+                    .eq(b, a)
+            },
+        )
     }
 
     fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
@@ -819,7 +901,8 @@
             }
             StatementKind::UserAssertTy(ref c_ty, ref local) => {
                 let local_ty = mir.local_decls()[*local].ty;
-                let (ty, _) = self.infcx
+                let (ty, _) = self
+                    .infcx
                     .instantiate_canonical_with_fresh_inference_vars(stmt.source_info.span, c_ty);
                 debug!(
                     "check_stmt: user_assert_ty ty={:?} local_ty={:?}",
@@ -1431,9 +1514,7 @@
                 }
             };
             let operand_ty = operand.ty(mir, tcx);
-            if let Err(terr) =
-                self.sub_types(operand_ty, field_ty, location.at_self())
-            {
+            if let Err(terr) = self.sub_types(operand_ty, field_ty, location.at_self()) {
                 span_mirbug!(
                     self,
                     rvalue,
@@ -1487,9 +1568,10 @@
                 if let Some(closure_region_requirements) =
                     tcx.mir_borrowck(*def_id).closure_requirements
                 {
+                    let dummy_body_id = ObligationCause::dummy().body_id;
                     closure_region_requirements.apply_requirements(
                         self.infcx,
-                        self.body_id,
+                        dummy_body_id,
                         location,
                         *def_id,
                         *substs,
@@ -1522,27 +1604,44 @@
 
     fn prove_predicates<T>(&mut self, predicates: T, location: Location)
     where
-        T: IntoIterator<Item = ty::Predicate<'tcx>>,
-        T::IntoIter: Clone,
+        T: IntoIterator<Item = ty::Predicate<'tcx>> + Clone,
     {
-        let predicates = predicates.into_iter();
+        let cause = ObligationCause::dummy();
+        let obligations: Vec<_> = predicates
+            .into_iter()
+            .map(|p| traits::Obligation::new(cause.clone(), self.param_env, p))
+            .collect();
+
+        // Micro-optimization
+        if obligations.is_empty() {
+            return;
+        }
+
+        // This intermediate vector is mildly unfortunate, in that we
+        // sometimes create it even when logging is disabled, but only
+        // if debug-info is enabled, and I doubt it is actually
+        // expensive. -nmatsakis
+        let predicates_vec: Vec<_> = if cfg!(debug_assertions) {
+            obligations.iter().map(|o| o.predicate).collect()
+        } else {
+            Vec::new()
+        };
 
         debug!(
             "prove_predicates(predicates={:?}, location={:?})",
-            predicates.clone().collect::<Vec<_>>(),
-            location,
+            predicates_vec, location,
         );
-        self.fully_perform_op(location.at_self(), |this| {
-            let cause = this.misc(this.last_span);
-            let obligations = predicates
-                .into_iter()
-                .map(|p| traits::Obligation::new(cause.clone(), this.param_env, p))
-                .collect();
-            Ok(InferOk {
-                value: (),
-                obligations,
-            })
-        }).unwrap()
+
+        self.fully_perform_op(
+            location.at_self(),
+            || format!("prove_predicates({:?})", predicates_vec),
+            |_this| {
+                Ok(InferOk {
+                    value: (),
+                    obligations,
+                })
+            },
+        ).unwrap()
     }
 
     fn typeck_mir(&mut self, mir: &Mir<'tcx>) {
@@ -1575,21 +1674,31 @@
     where
         T: fmt::Debug + TypeFoldable<'tcx>,
     {
+        // Micro-optimization: avoid work when we don't have to
+        if !value.has_projections() {
+            return value.clone();
+        }
+
         debug!("normalize(value={:?}, location={:?})", value, location);
-        self.fully_perform_op(location.to_locations(), |this| {
-            let Normalized { value, obligations } = this.infcx
-                .at(&this.misc(this.last_span), this.param_env)
-                .normalize(value)
-                .unwrap_or_else(|NoSolution| {
-                    span_bug!(
-                        this.last_span,
-                        "normalization of `{:?}` failed at {:?}",
-                        value,
-                        location,
-                    );
-                });
-            Ok(InferOk { value, obligations })
-        }).unwrap()
+        self.fully_perform_op(
+            location.to_locations(),
+            || format!("normalize(value={:?})", value),
+            |this| {
+                let Normalized { value, obligations } = this
+                    .infcx
+                    .at(&ObligationCause::dummy(), this.param_env)
+                    .normalize(value)
+                    .unwrap_or_else(|NoSolution| {
+                        span_bug!(
+                            this.last_span,
+                            "normalization of `{:?}` failed at {:?}",
+                            value,
+                            location,
+                        );
+                    });
+                Ok(InferOk { value, obligations })
+            },
+        ).unwrap()
     }
 }
 
@@ -1598,7 +1707,6 @@
 impl MirPass for TypeckMir {
     fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource, mir: &mut Mir<'tcx>) {
         let def_id = src.def_id;
-        let id = tcx.hir.as_local_node_id(def_id).unwrap();
         debug!("run_pass: {:?}", def_id);
 
         // When NLL is enabled, the borrow checker runs the typeck
@@ -1614,7 +1722,16 @@
         }
         let param_env = tcx.param_env(def_id);
         tcx.infer_ctxt().enter(|infcx| {
-            let _ = type_check_internal(&infcx, id, param_env, mir, &[], None, &mut |_| ());
+            let _ = type_check_internal(
+                &infcx,
+                def_id,
+                param_env,
+                mir,
+                &[],
+                None,
+                None,
+                &mut |_| (),
+            );
 
             // For verification purposes, we just ignore the resulting
             // region constraint sets. Not our problem. =)
diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs
index 2ff2284..590f991 100644
--- a/src/librustc_mir/dataflow/move_paths/builder.rs
+++ b/src/librustc_mir/dataflow/move_paths/builder.rs
@@ -119,8 +119,8 @@
     }
 
     fn create_move_path(&mut self, place: &Place<'tcx>) {
-        // This is an assignment, not a move, so this not being a valid
-        // move path is OK.
+        // This is an non-moving access (such as an overwrite or
+        // drop), so this not being a valid move path is OK.
         let _ = self.move_path_for(place);
     }
 
@@ -135,8 +135,9 @@
         let place_ty = proj.base.ty(mir, tcx).to_ty(tcx);
         match place_ty.sty {
             ty::TyRef(..) | ty::TyRawPtr(..) =>
-                return Err(MoveError::cannot_move_out_of(mir.source_info(self.loc).span,
-                                                         BorrowedContent)),
+                return Err(MoveError::cannot_move_out_of(
+                    mir.source_info(self.loc).span,
+                    BorrowedContent { target_ty: place.ty(mir, tcx).to_ty(tcx) })),
             ty::TyAdt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() =>
                 return Err(MoveError::cannot_move_out_of(mir.source_info(self.loc).span,
                                                          InteriorOfTypeWithDestructor {
diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs
index 610963a..a73e47b 100644
--- a/src/librustc_mir/dataflow/move_paths/mod.rs
+++ b/src/librustc_mir/dataflow/move_paths/mod.rs
@@ -277,9 +277,23 @@
 
 #[derive(Debug)]
 pub(crate) enum IllegalMoveOriginKind<'tcx> {
+    /// Illegal move due to attempt to move from `static` variable.
     Static,
-    BorrowedContent,
+
+    /// Illegal move due to attempt to move from behind a reference.
+    BorrowedContent {
+        /// The content's type: if erroneous code was trying to move
+        /// from `*x` where `x: &T`, then this will be `T`.
+        target_ty: ty::Ty<'tcx>,
+    },
+
+    /// Illegal move due to attempt to move from field of an ADT that
+    /// implements `Drop`. Rust maintains invariant that all `Drop`
+    /// ADT's remain fully-initialized so that user-defined destructor
+    /// can safely read from all of the ADT's fields.
     InteriorOfTypeWithDestructor { container_ty: ty::Ty<'tcx> },
+
+    /// Illegal move due to attempt to move out of a slice or array.
     InteriorOfSliceOrArray { ty: ty::Ty<'tcx>, is_index: bool, },
 }
 
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index f6f98f0..f23e10a 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -523,7 +523,7 @@
             let count = match cx.tcx.at(span).const_eval(cx.param_env.and(global_id)) {
                 Ok(cv) => cv.unwrap_usize(cx.tcx),
                 Err(e) => {
-                    e.report(cx.tcx, cx.tcx.def_span(def_id), "array length");
+                    e.report_as_error(cx.tcx.at(span), "could not evaluate array length");
                     0
                 },
             };
diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs
index 0a11397..7cef8a7 100644
--- a/src/librustc_mir/hair/pattern/check_match.rs
+++ b/src/librustc_mir/hair/pattern/check_match.rs
@@ -141,13 +141,13 @@
                 PatternError::FloatBug => {
                     // FIXME(#31407) this is only necessary because float parsing is buggy
                     ::rustc::middle::const_val::struct_error(
-                        self.tcx, pat_span,
+                        self.tcx.at(pat_span),
                         "could not evaluate float literal (see issue #31407)",
                     ).emit();
                 }
                 PatternError::NonConstPath(span) => {
                     ::rustc::middle::const_val::struct_error(
-                        self.tcx, span,
+                        self.tcx.at(span),
                         "runtime values cannot be referenced in patterns",
                     ).emit();
                 }
diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs
index 4cfe744..7dae795 100644
--- a/src/librustc_mir/hair/pattern/mod.rs
+++ b/src/librustc_mir/hair/pattern/mod.rs
@@ -695,7 +695,10 @@
                                 return self.const_to_pat(instance, value, id, span)
                             },
                             Err(err) => {
-                                err.report(self.tcx, span, "pattern");
+                                err.report_as_error(
+                                    self.tcx.at(span),
+                                    "could not evaluate constant pattern",
+                                );
                                 PatternKind::Wild
                             },
                         }
diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs
index 44832df..3fcf1b5 100644
--- a/src/librustc_mir/interpret/const_eval.rs
+++ b/src/librustc_mir/interpret/const_eval.rs
@@ -65,34 +65,12 @@
     cid: GlobalId<'tcx>,
     mir: &'mir mir::Mir<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
-) -> Option<(Value, Scalar, Ty<'tcx>)> {
+) -> EvalResult<'tcx, (Value, Scalar, Ty<'tcx>)> {
     ecx.with_fresh_body(|ecx| {
-        let res = eval_body_using_ecx(ecx, cid, Some(mir), param_env);
-        match res {
-            Ok(val) => Some(val),
-            Err(mut err) => {
-                ecx.report(&mut err, false, None);
-                None
-            }
-        }
+        eval_body_using_ecx(ecx, cid, Some(mir), param_env)
     })
 }
 
-pub fn eval_body<'a, 'tcx>(
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    cid: GlobalId<'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
-) -> Option<(Value, Scalar, Ty<'tcx>)> {
-    let (res, ecx) = eval_body_and_ecx(tcx, cid, None, param_env);
-    match res {
-        Ok(val) => Some(val),
-        Err(mut err) => {
-            ecx.report(&mut err, true, None);
-            None
-        }
-    }
-}
-
 pub fn value_to_const_value<'tcx>(
     ecx: &EvalContext<'_, '_, 'tcx, CompileTimeEvaluator>,
     val: Value,
@@ -124,9 +102,17 @@
     })();
     match val {
         Ok(val) => ty::Const::from_const_value(ecx.tcx.tcx, val, ty),
-        Err(mut err) => {
-            ecx.report(&mut err, true, None);
-            bug!("miri error occured when converting Value to ConstValue")
+        Err(err) => {
+            let (frames, span) = ecx.generate_stacktrace(None);
+            let err = ConstEvalErr {
+                span,
+                kind: ErrKind::Miri(err, frames).into(),
+            };
+            err.report_as_error(
+                ecx.tcx,
+                "failed to convert Value to ConstValue, this is a bug",
+            );
+            span_bug!(span, "miri error occured when converting Value to ConstValue")
         }
     }
 }
@@ -578,16 +564,17 @@
             val = ecx.try_read_by_ref(val, miri_ty)?;
         }
         Ok(value_to_const_value(&ecx, val, miri_ty))
-    }).map_err(|mut err| {
-        if tcx.is_static(def_id).is_some() {
-            ecx.report(&mut err, true, None);
-        }
+    }).map_err(|err| {
         let (trace, span) = ecx.generate_stacktrace(None);
         let err = ErrKind::Miri(err, trace);
-        ConstEvalErr {
+        let err = ConstEvalErr {
             kind: err.into(),
             span,
+        };
+        if tcx.is_static(def_id).is_some() {
+            err.report_as_error(ecx.tcx, "could not evaluate static initializer");
         }
+        err
     })
 }
 
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index 632f7ab..ea66727 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -3,19 +3,19 @@
 use rustc::hir::def_id::DefId;
 use rustc::hir::def::Def;
 use rustc::hir::map::definitions::DefPathData;
-use rustc::middle::const_val::{ConstVal, ErrKind};
+use rustc::middle::const_val::ConstVal;
 use rustc::mir;
 use rustc::ty::layout::{self, Size, Align, HasDataLayout, IntegerExt, LayoutOf, TyLayout};
 use rustc::ty::subst::{Subst, Substs};
 use rustc::ty::{self, Ty, TyCtxt, TypeAndMut};
-use rustc::ty::maps::TyCtxtAt;
+use rustc::ty::query::TyCtxtAt;
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
 use rustc::middle::const_val::FrameInfo;
 use syntax::codemap::{self, Span};
 use syntax::ast::Mutability;
 use rustc::mir::interpret::{
     GlobalId, Value, Scalar,
-    EvalError, EvalResult, EvalErrorKind, Pointer, ConstValue,
+    EvalResult, EvalErrorKind, Pointer, ConstValue,
 };
 use std::mem;
 
@@ -1056,15 +1056,7 @@
         } else {
             self.param_env
         };
-        self.tcx.const_eval(param_env.and(gid)).map_err(|err| match *err.kind {
-            ErrKind::Miri(ref err, _) => match err.kind {
-                EvalErrorKind::TypeckError |
-                EvalErrorKind::Layout(_) => EvalErrorKind::TypeckError.into(),
-                _ => EvalErrorKind::ReferencedConstant.into(),
-            },
-            ErrKind::TypeckError => EvalErrorKind::TypeckError.into(),
-            ref other => bug!("const eval returned {:?}", other),
-        })
+        self.tcx.const_eval(param_env.and(gid)).map_err(|err| EvalErrorKind::ReferencedConstant(err).into())
     }
 
     pub fn force_allocation(&mut self, place: Place) -> EvalResult<'tcx, Place> {
@@ -1626,7 +1618,7 @@
         let mut last_span = None;
         let mut frames = Vec::new();
         // skip 1 because the last frame is just the environment of the constant
-        for &Frame { instance, span, .. } in self.stack().iter().skip(1).rev() {
+        for &Frame { instance, span, mir, block, stmt, .. } in self.stack().iter().skip(1).rev() {
             // make sure we don't emit frames that are duplicates of the previous
             if explicit_span == Some(span) {
                 last_span = Some(span);
@@ -1644,84 +1636,22 @@
             } else {
                 instance.to_string()
             };
-            frames.push(FrameInfo { span, location });
+            let block = &mir.basic_blocks()[block];
+            let source_info = if stmt < block.statements.len() {
+                block.statements[stmt].source_info
+            } else {
+                block.terminator().source_info
+            };
+            let lint_root = match mir.source_scope_local_data {
+                mir::ClearCrossCrate::Set(ref ivs) => Some(ivs[source_info.scope].lint_root),
+                mir::ClearCrossCrate::Clear => None,
+            };
+            frames.push(FrameInfo { span, location, lint_root });
         }
         trace!("generate stacktrace: {:#?}, {:?}", frames, explicit_span);
         (frames, self.tcx.span)
     }
 
-    pub fn report(&self, e: &mut EvalError, as_err: bool, explicit_span: Option<Span>) {
-        match e.kind {
-            EvalErrorKind::Layout(_) |
-            EvalErrorKind::TypeckError => return,
-            _ => {},
-        }
-        if let Some(ref mut backtrace) = e.backtrace {
-            let mut trace_text = "\n\nAn error occurred in miri:\n".to_string();
-            backtrace.resolve();
-            write!(trace_text, "backtrace frames: {}\n", backtrace.frames().len()).unwrap();
-            'frames: for (i, frame) in backtrace.frames().iter().enumerate() {
-                if frame.symbols().is_empty() {
-                    write!(trace_text, "{}: no symbols\n", i).unwrap();
-                }
-                for symbol in frame.symbols() {
-                    write!(trace_text, "{}: ", i).unwrap();
-                    if let Some(name) = symbol.name() {
-                        write!(trace_text, "{}\n", name).unwrap();
-                    } else {
-                        write!(trace_text, "<unknown>\n").unwrap();
-                    }
-                    write!(trace_text, "\tat ").unwrap();
-                    if let Some(file_path) = symbol.filename() {
-                        write!(trace_text, "{}", file_path.display()).unwrap();
-                    } else {
-                        write!(trace_text, "<unknown_file>").unwrap();
-                    }
-                    if let Some(line) = symbol.lineno() {
-                        write!(trace_text, ":{}\n", line).unwrap();
-                    } else {
-                        write!(trace_text, "\n").unwrap();
-                    }
-                }
-            }
-            error!("{}", trace_text);
-        }
-        if let Some(frame) = self.stack().last() {
-            let block = &frame.mir.basic_blocks()[frame.block];
-            let span = explicit_span.unwrap_or_else(|| if frame.stmt < block.statements.len() {
-                block.statements[frame.stmt].source_info.span
-            } else {
-                block.terminator().source_info.span
-            });
-            trace!("reporting const eval failure at {:?}", span);
-            let mut err = if as_err {
-                ::rustc::middle::const_val::struct_error(*self.tcx, span, "constant evaluation error")
-            } else {
-                let node_id = self
-                    .stack()
-                    .iter()
-                    .rev()
-                    .filter_map(|frame| self.tcx.hir.as_local_node_id(frame.instance.def_id()))
-                    .next()
-                    .expect("some part of a failing const eval must be local");
-                self.tcx.struct_span_lint_node(
-                    ::rustc::lint::builtin::CONST_ERR,
-                    node_id,
-                    span,
-                    "constant evaluation error",
-                )
-            };
-            let (frames, span) = self.generate_stacktrace(explicit_span);
-            err.span_label(span, e.to_string());
-            for FrameInfo { span, location } in frames {
-                err.span_note(span, &format!("inside call to `{}`", location));
-            }
-            err.emit();
-        } else {
-            self.tcx.sess.err(&e.to_string());
-        }
-    }
-
     pub fn sign_extend(&self, value: u128, ty: Ty<'tcx>) -> EvalResult<'tcx, u128> {
         super::sign_extend(self.tcx.tcx, value, ty)
     }
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index dc56de4..ad571fb 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -4,10 +4,10 @@
 use rustc::hir::def_id::DefId;
 use rustc::ty::Instance;
 use rustc::ty::ParamEnv;
-use rustc::ty::maps::TyCtxtAt;
+use rustc::ty::query::TyCtxtAt;
 use rustc::ty::layout::{self, Align, TargetDataLayout, Size};
 use syntax::ast::Mutability;
-use rustc::middle::const_val::{ConstVal, ErrKind};
+use rustc::middle::const_val::ConstVal;
 
 use rustc_data_structures::fx::{FxHashSet, FxHashMap};
 use rustc::mir::interpret::{Pointer, AllocId, Allocation, AccessKind, Value,
@@ -285,16 +285,10 @@
             instance,
             promoted: None,
         };
-        self.tcx.const_eval(ParamEnv::reveal_all().and(gid)).map_err(|err| {
-            match *err.kind {
-                ErrKind::Miri(ref err, _) => match err.kind {
-                    EvalErrorKind::TypeckError |
-                    EvalErrorKind::Layout(_) => EvalErrorKind::TypeckError.into(),
-                    _ => EvalErrorKind::ReferencedConstant.into(),
-                },
-                ErrKind::TypeckError => EvalErrorKind::TypeckError.into(),
-                ref other => bug!("const eval returned {:?}", other),
-            }
+        self.tcx.const_eval(ParamEnv::reveal_all().and(gid)).map_err(|_| {
+            // no need to report anything, the const_eval call takes care of that for statics
+            assert!(self.tcx.is_static(def_id).is_some());
+            EvalErrorKind::TypeckError.into()
         }).map(|val| {
             let const_val = match val.val {
                 ConstVal::Value(val) => val,
diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs
index b5b4ac6..3afcd6f 100644
--- a/src/librustc_mir/interpret/mod.rs
+++ b/src/librustc_mir/interpret/mod.rs
@@ -21,7 +21,6 @@
 pub use self::const_eval::{
     eval_promoted,
     mk_borrowck_eval_cx,
-    eval_body,
     CompileTimeEvaluator,
     const_value_to_allocation_provider,
     const_eval_provider,
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index c1bcffe..51b33fa 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -120,7 +120,7 @@
         variant: Option<usize>,
         field: mir::Field,
         base_ty: Ty<'tcx>,
-    ) -> EvalResult<'tcx, Option<(Value, Ty<'tcx>)>> {
+    ) -> EvalResult<'tcx, ValTy<'tcx>> {
         let mut base_layout = self.layout_of(base_ty)?;
         if let Some(variant_index) = variant {
             base_layout = base_layout.for_variant(self, variant_index);
@@ -128,21 +128,34 @@
         let field_index = field.index();
         let field = base_layout.field(self, field_index)?;
         if field.size.bytes() == 0 {
-            return Ok(Some((Value::Scalar(Scalar::undef()), field.ty)))
+            return Ok(ValTy {
+                value: Value::Scalar(Scalar::undef()),
+                ty: field.ty,
+            });
         }
         let offset = base_layout.fields.offset(field_index);
-        match base {
+        let value = match base {
             // the field covers the entire type
             Value::ScalarPair(..) |
-            Value::Scalar(_) if offset.bytes() == 0 && field.size == base_layout.size => Ok(Some((base, field.ty))),
-            // split fat pointers, 2 element tuples, ...
-            Value::ScalarPair(a, b) if base_layout.fields.count() == 2 => {
-                let val = [a, b][field_index];
-                Ok(Some((Value::Scalar(val), field.ty)))
+            Value::Scalar(_) if offset.bytes() == 0 && field.size == base_layout.size => base,
+            // extract fields from types with `ScalarPair` ABI
+            Value::ScalarPair(a, b) => {
+                let val = if offset.bytes() == 0 { a } else { b };
+                Value::Scalar(val)
             },
-            // FIXME(oli-obk): figure out whether we should be calling `try_read_value` here
-            _ => Ok(None),
-        }
+            Value::ByRef(base_ptr, align) => {
+                let offset = base_layout.fields.offset(field_index);
+                let ptr = base_ptr.ptr_offset(offset, self)?;
+                let align = align.min(base_layout.align).min(field.align);
+                assert!(!field.is_unsized());
+                Value::ByRef(ptr, align)
+            },
+            Value::Scalar(val) => bug!("field access on non aggregate {:?}, {:?}", val, base_ty),
+        };
+        Ok(ValTy {
+            value,
+            ty: field.ty,
+        })
     }
 
     fn try_read_place_projection(
@@ -156,7 +169,7 @@
         };
         let base_ty = self.place_ty(&proj.base);
         match proj.elem {
-            Field(field, _) => Ok(self.read_field(base, None, field, base_ty)?.map(|(f, _)| f)),
+            Field(field, _) => Ok(Some(self.read_field(base, None, field, base_ty)?.value)),
             // The NullablePointer cases should work fine, need to take care for normal enums
             Downcast(..) |
             Subslice { .. } |
diff --git a/src/librustc_mir/interpret/terminator/mod.rs b/src/librustc_mir/interpret/terminator/mod.rs
index 9151bfb..2994b1b 100644
--- a/src/librustc_mir/interpret/terminator/mod.rs
+++ b/src/librustc_mir/interpret/terminator/mod.rs
@@ -4,7 +4,7 @@
 use syntax::codemap::Span;
 use rustc_target::spec::abi::Abi;
 
-use rustc::mir::interpret::{EvalResult, Scalar, Value};
+use rustc::mir::interpret::EvalResult;
 use super::{EvalContext, Place, Machine, ValTy};
 
 use rustc_data_structures::indexed_vec::Idx;
@@ -338,65 +338,17 @@
 
                         // unpack and write all other args
                         let layout = self.layout_of(args[1].ty)?;
-                        if let ty::TyTuple(..) = args[1].ty.sty {
+                        if let ty::TyTuple(_) = args[1].ty.sty {
+                            if layout.is_zst() {
+                                // Nothing to do, no need to unpack zsts
+                                return Ok(());
+                            }
                             if self.frame().mir.args_iter().count() == layout.fields.count() + 1 {
-                                match args[1].value {
-                                    Value::ByRef(ptr, align) => {
-                                        for (i, arg_local) in arg_locals.enumerate() {
-                                            let field = layout.field(&self, i)?;
-                                            let offset = layout.fields.offset(i);
-                                            let arg = Value::ByRef(ptr.ptr_offset(offset, &self)?,
-                                                                   align.min(field.align));
-                                            let dest =
-                                                self.eval_place(&mir::Place::Local(arg_local))?;
-                                            trace!(
-                                                "writing arg {:?} to {:?} (type: {})",
-                                                arg,
-                                                dest,
-                                                field.ty
-                                            );
-                                            let valty = ValTy {
-                                                value: arg,
-                                                ty: field.ty,
-                                            };
-                                            self.write_value(valty, dest)?;
-                                        }
-                                    }
-                                    Value::Scalar(Scalar::Bits { defined: 0, .. }) => {}
-                                    other => {
-                                        trace!("{:#?}, {:#?}", other, layout);
-                                        let mut layout = layout;
-                                        'outer: loop {
-                                            for i in 0..layout.fields.count() {
-                                                let field = layout.field(&self, i)?;
-                                                if layout.fields.offset(i).bytes() == 0 && layout.size == field.size {
-                                                    layout = field;
-                                                    continue 'outer;
-                                                }
-                                            }
-                                            break;
-                                        }
-                                        {
-                                            let mut write_next = |value| {
-                                                let dest = self.eval_place(&mir::Place::Local(
-                                                    arg_locals.next().unwrap(),
-                                                ))?;
-                                                let valty = ValTy {
-                                                    value: Value::Scalar(value),
-                                                    ty: layout.ty,
-                                                };
-                                                self.write_value(valty, dest)
-                                            };
-                                            match other {
-                                                Value::Scalar(value) | Value::ScalarPair(value, _) => write_next(value)?,
-                                                _ => unreachable!(),
-                                            }
-                                            if let Value::ScalarPair(_, value) = other {
-                                                write_next(value)?;
-                                            }
-                                        }
-                                        assert!(arg_locals.next().is_none());
-                                    }
+                                for (i, arg_local) in arg_locals.enumerate() {
+                                    let field = mir::Field::new(i);
+                                    let valty = self.read_field(args[1].value, None, field, args[1].ty)?;
+                                    let dest = self.eval_place(&mir::Place::Local(arg_local))?;
+                                    self.write_value(valty, dest)?;
                                 }
                             } else {
                                 trace!("manual impl of rust-call ABI");
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index 34eb444..d815d4a 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -67,7 +67,7 @@
 pub mod monomorphize;
 
 pub use hair::pattern::check_crate as matchck_crate;
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 
 pub fn provide(providers: &mut Providers) {
     borrow_check::provide(providers);
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index a8a50e1..1fb1217 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -388,7 +388,10 @@
                 Ok(val) => collect_const(tcx, val, instance.substs, &mut neighbors),
                 Err(err) => {
                     let span = tcx.def_span(def_id);
-                    err.report(tcx, span, "static");
+                    err.report_as_error(
+                        tcx.at(span),
+                        "could not evaluate static initializer",
+                    );
                 }
             }
         }
@@ -941,6 +944,7 @@
             hir::ItemTy(..)          |
             hir::ItemTrait(..)       |
             hir::ItemTraitAlias(..)  |
+            hir::ItemExistential(..) |
             hir::ItemMod(..)         => {
                 // Nothing to do, just keep recursing...
             }
@@ -1187,13 +1191,25 @@
     let param_env = ty::ParamEnv::reveal_all();
     for i in 0..mir.promoted.len() {
         use rustc_data_structures::indexed_vec::Idx;
+        let i = Promoted::new(i);
         let cid = GlobalId {
             instance,
-            promoted: Some(Promoted::new(i)),
+            promoted: Some(i),
         };
         match tcx.const_eval(param_env.and(cid)) {
             Ok(val) => collect_const(tcx, val, instance.substs, output),
-            Err(_) => {},
+            Err(err) => {
+                use rustc::middle::const_val::ErrKind;
+                use rustc::mir::interpret::EvalErrorKind;
+                if let ErrKind::Miri(ref miri, ..) = *err.kind {
+                    if let EvalErrorKind::ReferencedConstant(_) = miri.kind {
+                        err.report_as_error(
+                            tcx.at(mir.promoted[i].span),
+                            "erroneous constant used",
+                        );
+                    }
+                }
+            },
         }
     }
 }
@@ -1236,7 +1252,10 @@
                 Ok(val) => val.val,
                 Err(err) => {
                     let span = tcx.def_span(def_id);
-                    err.report(tcx, span, "constant");
+                    err.report_as_error(
+                        tcx.at(span),
+                        "constant evaluation error",
+                    );
                     return;
                 }
             }
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index d4a9b2c..f11d802 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -14,7 +14,7 @@
 use rustc::mir::*;
 use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind};
 use rustc::ty::subst::{Subst, Substs};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
 
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index fedd077..5f8f9ac 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -12,7 +12,7 @@
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_data_structures::sync::Lrc;
 
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::ty::{self, TyCtxt};
 use rustc::hir;
 use rustc::hir::def_id::DefId;
@@ -362,8 +362,8 @@
         format!("#[derive] can't be used on a #[repr(packed)] struct with \
                  type parameters (error E0133)")
     } else {
-        format!("#[derive] can't be used on a non-Copy #[repr(packed)] struct \
-                 (error E0133)")
+        format!("#[derive] can't be used on a #[repr(packed)] struct that \
+                 does not derive Copy (error E0133)")
     };
     tcx.lint_node(SAFE_PACKED_BORROWS,
                   lint_node_id,
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index ef61fe0..2438281 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -17,7 +17,7 @@
 use rustc::mir::{NullOp, StatementKind, Statement, BasicBlock, LocalKind};
 use rustc::mir::{TerminatorKind, ClearCrossCrate, SourceInfo, BinOp, ProjectionElem};
 use rustc::mir::visit::{Visitor, PlaceContext};
-use rustc::middle::const_val::ConstVal;
+use rustc::middle::const_val::{ConstVal, ConstEvalErr, ErrKind};
 use rustc::ty::{TyCtxt, self, Instance};
 use rustc::mir::interpret::{Value, Scalar, GlobalId, EvalResult};
 use interpret::EvalContext;
@@ -29,7 +29,7 @@
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc::ty::ParamEnv;
 use rustc::ty::layout::{
-    LayoutOf, TyLayout, LayoutError, LayoutCx,
+    LayoutOf, TyLayout, LayoutError,
     HasTyCtxt, TargetDataLayout, HasDataLayout,
 };
 
@@ -121,17 +121,37 @@
 
     fn use_ecx<F, T>(
         &mut self,
-        span: Span,
+        source_info: SourceInfo,
         f: F
     ) -> Option<T>
     where
         F: FnOnce(&mut Self) -> EvalResult<'tcx, T>,
     {
-        self.ecx.tcx.span = span;
+        self.ecx.tcx.span = source_info.span;
+        let lint_root = match self.mir.source_scope_local_data {
+            ClearCrossCrate::Set(ref ivs) => {
+                use rustc_data_structures::indexed_vec::Idx;
+                //FIXME(#51314): remove this check
+                if source_info.scope.index() >= ivs.len() {
+                    return None;
+                }
+                ivs[source_info.scope].lint_root
+            },
+            ClearCrossCrate::Clear => return None,
+        };
         let r = match f(self) {
             Ok(val) => Some(val),
-            Err(mut err) => {
-                self.ecx.report(&mut err, false, Some(span));
+            Err(err) => {
+                let (frames, span) = self.ecx.generate_stacktrace(None);
+                let err = ConstEvalErr {
+                    span,
+                    kind: ErrKind::Miri(err, frames).into(),
+                };
+                err.report_as_lint(
+                    self.ecx.tcx,
+                    "this expression will panic at runtime",
+                    lint_root,
+                );
                 None
             },
         };
@@ -139,30 +159,37 @@
         r
     }
 
-    fn const_eval(&mut self, cid: GlobalId<'tcx>, span: Span) -> Option<Const<'tcx>> {
+    fn const_eval(&mut self, cid: GlobalId<'tcx>, source_info: SourceInfo) -> Option<Const<'tcx>> {
         let value = match self.tcx.const_eval(self.param_env.and(cid)) {
             Ok(val) => val,
             Err(err) => {
-                err.report(self.tcx, err.span, "constant propagated");
+                err.report_as_error(
+                    self.tcx.at(err.span),
+                    "constant evaluation error",
+                );
                 return None;
             },
         };
         let val = match value.val {
             ConstVal::Value(v) => {
-                self.use_ecx(span, |this| this.ecx.const_value_to_value(v, value.ty))?
+                self.use_ecx(source_info, |this| this.ecx.const_value_to_value(v, value.ty))?
             },
             _ => bug!("eval produced: {:?}", value),
         };
-        let val = (val, value.ty, span);
+        let val = (val, value.ty, source_info.span);
         trace!("evaluated {:?} to {:?}", cid, val);
         Some(val)
     }
 
-    fn eval_constant(&mut self, c: &Constant<'tcx>) -> Option<Const<'tcx>> {
+    fn eval_constant(
+        &mut self,
+        c: &Constant<'tcx>,
+        source_info: SourceInfo,
+    ) -> Option<Const<'tcx>> {
         match c.literal {
             Literal::Value { value } => match value.val {
                 ConstVal::Value(v) => {
-                    let v = self.use_ecx(c.span, |this| {
+                    let v = self.use_ecx(source_info, |this| {
                         this.ecx.const_value_to_value(v, value.ty)
                     })?;
                     Some((v, value.ty, c.span))
@@ -178,7 +205,7 @@
                         instance,
                         promoted: None,
                     };
-                    self.const_eval(cid, c.span)
+                    self.const_eval(cid, source_info)
                 },
             },
             // evaluate the promoted and replace the constant with the evaluated result
@@ -196,10 +223,9 @@
                 };
                 // cannot use `const_eval` here, because that would require having the MIR
                 // for the current function available, but we're producing said MIR right now
-                let span = self.mir.span;
-                let (value, _, ty) = self.use_ecx(span, |this| {
-                    Ok(eval_promoted(&mut this.ecx, cid, this.mir, this.param_env))
-                })??;
+                let (value, _, ty) = self.use_ecx(source_info, |this| {
+                    eval_promoted(&mut this.ecx, cid, this.mir, this.param_env)
+                })?;
                 let val = (value, ty, c.span);
                 trace!("evaluated {:?} to {:?}", c, val);
                 Some(val)
@@ -207,31 +233,17 @@
         }
     }
 
-    fn eval_place(&mut self, place: &Place<'tcx>) -> Option<Const<'tcx>> {
+    fn eval_place(&mut self, place: &Place<'tcx>, source_info: SourceInfo) -> Option<Const<'tcx>> {
         match *place {
             Place::Local(loc) => self.places[loc].clone(),
             Place::Projection(ref proj) => match proj.elem {
                 ProjectionElem::Field(field, _) => {
                     trace!("field proj on {:?}", proj.base);
-                    let (base, ty, span) = self.eval_place(&proj.base)?;
-                    match base {
-                        Value::ScalarPair(a, b) => {
-                            trace!("by val pair: {:?}, {:?}", a, b);
-                            let base_layout = self.tcx.layout_of(self.param_env.and(ty)).ok()?;
-                            trace!("layout computed");
-                            use rustc_data_structures::indexed_vec::Idx;
-                            let field_index = field.index();
-                            let val = [a, b][field_index];
-                            let cx = LayoutCx {
-                                tcx: self.tcx,
-                                param_env: self.param_env,
-                            };
-                            let field = base_layout.field(cx, field_index).ok()?;
-                            trace!("projection resulted in: {:?}", val);
-                            Some((Value::Scalar(val), field.ty, span))
-                        },
-                        _ => None,
-                    }
+                    let (base, ty, span) = self.eval_place(&proj.base, source_info)?;
+                    let valty = self.use_ecx(source_info, |this| {
+                        this.ecx.read_field(base, None, field, ty)
+                    })?;
+                    Some((valty.value, valty.ty, span))
                 },
                 _ => None,
             },
@@ -239,10 +251,11 @@
         }
     }
 
-    fn eval_operand(&mut self, op: &Operand<'tcx>) -> Option<Const<'tcx>> {
+    fn eval_operand(&mut self, op: &Operand<'tcx>, source_info: SourceInfo) -> Option<Const<'tcx>> {
         match *op {
-            Operand::Constant(ref c) => self.eval_constant(c),
-            Operand::Move(ref place) | Operand::Copy(ref place) => self.eval_place(place),
+            Operand::Constant(ref c) => self.eval_constant(c, source_info),
+            | Operand::Move(ref place)
+            | Operand::Copy(ref place) => self.eval_place(place, source_info),
         }
     }
 
@@ -254,23 +267,13 @@
     ) -> Option<Const<'tcx>> {
         let span = source_info.span;
         match *rvalue {
-            // No need to overwrite an already evaluated constant
-            Rvalue::Use(Operand::Constant(box Constant {
-                literal: Literal::Value {
-                    value: &ty::Const {
-                        val: ConstVal::Value(_),
-                        ..
-                    },
-                },
-                ..
-            })) => None,
             // This branch exists for the sanity type check
             Rvalue::Use(Operand::Constant(ref c)) => {
                 assert_eq!(c.ty, place_ty);
-                self.eval_constant(c)
+                self.eval_constant(c, source_info)
             },
             Rvalue::Use(ref op) => {
-                self.eval_operand(op)
+                self.eval_operand(op, source_info)
             },
             Rvalue::Repeat(..) |
             Rvalue::Ref(..) |
@@ -303,17 +306,17 @@
                     return None;
                 }
 
-                let val = self.eval_operand(arg)?;
-                let prim = self.use_ecx(span, |this| {
+                let val = self.eval_operand(arg, source_info)?;
+                let prim = self.use_ecx(source_info, |this| {
                     this.ecx.value_to_scalar(ValTy { value: val.0, ty: val.1 })
                 })?;
-                let val = self.use_ecx(span, |this| this.ecx.unary_op(op, prim, val.1))?;
+                let val = self.use_ecx(source_info, |this| this.ecx.unary_op(op, prim, val.1))?;
                 Some((Value::Scalar(val), place_ty, span))
             }
             Rvalue::CheckedBinaryOp(op, ref left, ref right) |
             Rvalue::BinaryOp(op, ref left, ref right) => {
                 trace!("rvalue binop {:?} for {:?} and {:?}", op, left, right);
-                let right = self.eval_operand(right)?;
+                let right = self.eval_operand(right, source_info)?;
                 let def_id = if self.tcx.is_closure(self.source.def_id) {
                     self.tcx.closure_base_def_id(self.source.def_id)
                 } else {
@@ -325,7 +328,7 @@
                     return None;
                 }
 
-                let r = self.use_ecx(span, |this| {
+                let r = self.use_ecx(source_info, |this| {
                     this.ecx.value_to_scalar(ValTy { value: right.0, ty: right.1 })
                 })?;
                 if op == BinOp::Shr || op == BinOp::Shl {
@@ -356,12 +359,12 @@
                         return None;
                     }
                 }
-                let left = self.eval_operand(left)?;
-                let l = self.use_ecx(span, |this| {
+                let left = self.eval_operand(left, source_info)?;
+                let l = self.use_ecx(source_info, |this| {
                     this.ecx.value_to_scalar(ValTy { value: left.0, ty: left.1 })
                 })?;
                 trace!("const evaluating {:?} for {:?} and {:?}", op, left, right);
-                let (val, overflow) = self.use_ecx(span, |this| {
+                let (val, overflow) = self.use_ecx(source_info, |this| {
                     this.ecx.binary_op(op, l, left.1, r, right.1)
                 })?;
                 let val = if let Rvalue::CheckedBinaryOp(..) = *rvalue {
@@ -372,11 +375,8 @@
                 } else {
                     if overflow {
                         use rustc::mir::interpret::EvalErrorKind;
-                        let mut err = EvalErrorKind::Overflow(op).into();
-                        self.use_ecx(span, |this| {
-                            this.ecx.report(&mut err, false, Some(span));
-                            Ok(())
-                        });
+                        let err = EvalErrorKind::Overflow(op).into();
+                        let _: Option<()> = self.use_ecx(source_info, |_| Err(err));
                         return None;
                     }
                     Value::Scalar(val)
@@ -455,7 +455,8 @@
     ) {
         trace!("visit_constant: {:?}", constant);
         self.super_constant(constant, location);
-        self.eval_constant(constant);
+        let source_info = *self.mir.source_info(location);
+        self.eval_constant(constant, source_info);
     }
 
     fn visit_statement(
@@ -490,8 +491,9 @@
         location: Location,
     ) {
         self.super_terminator_kind(block, kind, location);
+        let source_info = *self.mir.source_info(location);
         if let TerminatorKind::Assert { expected, msg, cond, .. } = kind {
-            if let Some(value) = self.eval_operand(cond) {
+            if let Some(value) = self.eval_operand(cond, source_info) {
                 trace!("assertion on {:?} should be {:?}", value, expected);
                 if Value::Scalar(Scalar::from_bool(*expected)) != value.0 {
                     // poison all places this operand references so that further code
@@ -526,13 +528,15 @@
                         DivisionByZero |
                         RemainderByZero => msg.description().to_owned(),
                         BoundsCheck { ref len, ref index } => {
-                            let len = self.eval_operand(len).expect("len must be const");
+                            let len = self
+                                .eval_operand(len, source_info)
+                                .expect("len must be const");
                             let len = match len.0 {
                                 Value::Scalar(Scalar::Bits { bits, ..}) => bits,
                                 _ => bug!("const len not primitive: {:?}", len),
                             };
                             let index = self
-                                .eval_operand(index)
+                                .eval_operand(index, source_info)
                                 .expect("index must be const");
                             let index = match index.0 {
                                 Value::Scalar(Scalar::Bits { bits, .. }) => bits,
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index a1845f7..cb57dc5 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -126,9 +126,8 @@
                     continue;
                 }
 
-                let callee_mir = match self.tcx.try_get_query::<ty::queries::optimized_mir>(
-                                                                           callsite.location.span,
-                                                                           callsite.callee) {
+                let callee_mir = match self.tcx.try_optimized_mir(callsite.location.span,
+                                                                  callsite.callee) {
                     Ok(callee_mir) if self.should_inline(callsite, callee_mir) => {
                         self.tcx.subst_and_normalize_erasing_regions(
                             &callsite.substs,
diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs
index e2f2312..06be2bb 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/src/librustc_mir/transform/mod.rs
@@ -13,7 +13,7 @@
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc::mir::{Mir, Promoted};
 use rustc::ty::TyCtxt;
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::ty::steal::Steal;
 use rustc::hir;
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 03ca85f..6448ba1 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -24,7 +24,7 @@
 use rustc::traits::{self, TraitEngine};
 use rustc::ty::{self, TyCtxt, Ty, TypeFoldable};
 use rustc::ty::cast::CastTy;
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::mir::*;
 use rustc::mir::traversal::ReversePostorder;
 use rustc::mir::visit::{PlaceContext, Visitor};
@@ -566,8 +566,14 @@
 
                         ProjectionElem::Field(..) |
                         ProjectionElem::Index(_) => {
-                            if this.mode != Mode::Fn &&
-                               this.qualif.intersects(Qualif::STATIC) {
+                            if this.mode == Mode::Fn {
+                                let base_ty = proj.base.ty(this.mir, this.tcx).to_ty(this.tcx);
+                                if let Some(def) = base_ty.ty_adt_def() {
+                                    if def.is_union() {
+                                        this.not_const();
+                                    }
+                                }
+                            } else if this.qualif.intersects(Qualif::STATIC) {
                                 span_err!(this.tcx.sess, this.span, E0494,
                                           "cannot refer to the interior of another \
                                            static, use a constant instead");
diff --git a/src/librustc_mir/util/borrowck_errors.rs b/src/librustc_mir/util/borrowck_errors.rs
index d6b3e67..d01b90a 100644
--- a/src/librustc_mir/util/borrowck_errors.rs
+++ b/src/librustc_mir/util/borrowck_errors.rs
@@ -312,15 +312,19 @@
         self.cancel_if_wrong_origin(err, o)
     }
 
+    /// Signal an error due to an attempt to move out of the interior
+    /// of an array or slice. `is_index` is None when error origin
+    /// didn't capture whether there was an indexing operation or not.
     fn cannot_move_out_of_interior_noncopy(self,
                                            move_from_span: Span,
                                            ty: ty::Ty,
-                                           is_index: bool,
+                                           is_index: Option<bool>,
                                            o: Origin)
                                            -> DiagnosticBuilder<'cx>
     {
         let type_name = match (&ty.sty, is_index) {
-            (&ty::TyArray(_, _), true) => "array",
+            (&ty::TyArray(_, _), Some(true)) |
+            (&ty::TyArray(_, _), None) => "array",
             (&ty::TySlice(_),    _) => "slice",
             _ => span_bug!(move_from_span, "this path should not cause illegal move"),
         };
diff --git a/src/librustc_msan/lib.rs b/src/librustc_msan/lib.rs
index 81a09e7..a7aeed7 100644
--- a/src/librustc_msan/lib.rs
+++ b/src/librustc_msan/lib.rs
@@ -9,10 +9,9 @@
 // except according to those terms.
 
 #![sanitizer_runtime]
-#![feature(sanitizer_runtime)]
 #![feature(alloc_system)]
-#![feature(allocator_api)]
-#![feature(global_allocator)]
+#![cfg_attr(stage0, feature(global_allocator))]
+#![feature(sanitizer_runtime)]
 #![feature(staged_api)]
 #![no_std]
 #![unstable(feature = "sanitizer_runtime_lib",
diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs
index b6b5edc..41f1e78 100644
--- a/src/librustc_passes/lib.rs
+++ b/src/librustc_passes/lib.rs
@@ -32,7 +32,7 @@
 extern crate syntax_pos;
 extern crate rustc_errors as errors;
 
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 
 mod diagnostics;
 
diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs
index 52ceb3f..51b2988 100644
--- a/src/librustc_passes/rvalue_promotion.rs
+++ b/src/librustc_passes/rvalue_promotion.rs
@@ -32,7 +32,7 @@
 use rustc::middle::mem_categorization as mc;
 use rustc::middle::mem_categorization::Categorization;
 use rustc::ty::{self, Ty, TyCtxt};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::ty::subst::Substs;
 use rustc::util::nodemap::{ItemLocalSet, NodeSet};
 use rustc::hir;
@@ -150,6 +150,23 @@
                 span.allows_unstable();
         }
     }
+
+    /// While the `ExprUseVisitor` walks, we will identify which
+    /// expressions are borrowed, and insert their ids into this
+    /// table. Actually, we insert the "borrow-id", which is normally
+    /// the id of the expession being borrowed: but in the case of
+    /// `ref mut` borrows, the `id` of the pattern is
+    /// inserted. Therefore later we remove that entry from the table
+    /// and transfer it over to the value being matched. This will
+    /// then prevent said value from being promoted.
+    fn remove_mut_rvalue_borrow(&mut self, pat: &hir::Pat) -> bool {
+        let mut any_removed = false;
+        pat.walk(|p| {
+            any_removed |= self.mut_rvalue_borrows.remove(&p.id);
+            true
+        });
+        any_removed
+    }
 }
 
 impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> {
@@ -200,9 +217,15 @@
     fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt) {
         match stmt.node {
             hir::StmtDecl(ref decl, _) => {
-                match decl.node {
-                    hir::DeclLocal(_) => {
+                match &decl.node {
+                    hir::DeclLocal(local) => {
                         self.promotable = false;
+
+                        if self.remove_mut_rvalue_borrow(&local.pat) {
+                            if let Some(init) = &local.init {
+                                self.mut_rvalue_borrows.insert(init.id);
+                            }
+                        }
                     }
                     // Item statements are allowed
                     hir::DeclItem(_) => {}
@@ -229,9 +252,7 @@
             // patterns and set that on the discriminator.
             let mut mut_borrow = false;
             for pat in arms.iter().flat_map(|arm| &arm.pats) {
-                if self.mut_rvalue_borrows.remove(&pat.id) {
-                    mut_borrow = true;
-                }
+                mut_borrow = self.remove_mut_rvalue_borrow(pat);
             }
             if mut_borrow {
                 self.mut_rvalue_borrows.insert(discr.id);
@@ -424,9 +445,16 @@
             }
         }
 
+        hir::ExprField(ref expr, _) => {
+            if let Some(def) = v.tables.expr_ty(expr).ty_adt_def() {
+                if def.is_union() {
+                    v.promotable = false
+                }
+            }
+        }
+
         hir::ExprBlock(..) |
         hir::ExprIndex(..) |
-        hir::ExprField(..) |
         hir::ExprArray(_) |
         hir::ExprType(..) |
         hir::ExprTup(..) => {}
@@ -498,6 +526,14 @@
               _loan_region: ty::Region<'tcx>,
               bk: ty::BorrowKind,
               loan_cause: euv::LoanCause) {
+        debug!(
+            "borrow(borrow_id={:?}, cmt={:?}, bk={:?}, loan_cause={:?})",
+            borrow_id,
+            cmt,
+            bk,
+            loan_cause,
+        );
+
         // Kind of hacky, but we allow Unsafe coercions in constants.
         // These occur when we convert a &T or *T to a *U, as well as
         // when making a thin pointer (e.g., `*T`) into a fat pointer
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index bfb8c28..2910920 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -14,6 +14,8 @@
 
 #![feature(rustc_diagnostic_macros)]
 
+#![recursion_limit="256"]
+
 #[macro_use] extern crate rustc;
 #[macro_use] extern crate syntax;
 extern crate rustc_typeck;
@@ -29,7 +31,7 @@
 use rustc::middle::privacy::{AccessLevel, AccessLevels};
 use rustc::ty::{self, TyCtxt, Ty, TypeFoldable, GenericParamDefKind};
 use rustc::ty::fold::TypeVisitor;
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::ty::subst::UnpackedKind;
 use rustc::util::nodemap::NodeSet;
 use syntax::ast::{self, CRATE_NODE_ID, Ident};
@@ -158,6 +160,7 @@
             hir::ItemGlobalAsm(..) | hir::ItemFn(..) | hir::ItemMod(..) |
             hir::ItemStatic(..) | hir::ItemStruct(..) |
             hir::ItemTrait(..) | hir::ItemTraitAlias(..) |
+            hir::ItemExistential(..) |
             hir::ItemTy(..) | hir::ItemUnion(..) | hir::ItemUse(..) => {
                 if item.vis == hir::Public { self.prev_level } else { None }
             }
@@ -210,6 +213,7 @@
                     }
                 }
             }
+            hir::ItemExistential(..) |
             hir::ItemUse(..) | hir::ItemStatic(..) | hir::ItemConst(..) |
             hir::ItemGlobalAsm(..) | hir::ItemTy(..) | hir::ItemMod(..) | hir::ItemTraitAlias(..) |
             hir::ItemFn(..) | hir::ItemExternCrate(..) => {}
@@ -225,6 +229,8 @@
             hir::ItemUse(..) => {}
             // The interface is empty
             hir::ItemGlobalAsm(..) => {}
+            // Checked by visit_ty
+            hir::ItemExistential(..) => {}
             // Visit everything
             hir::ItemConst(..) | hir::ItemStatic(..) |
             hir::ItemFn(..) | hir::ItemTy(..) => {
@@ -386,10 +392,10 @@
     }
 
     fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
-        if let hir::TyImplTraitExistential(..) = ty.node {
-            if self.get(ty.id).is_some() {
-                // Reach the (potentially private) type and the API being exposed.
-                self.reach(ty.id).ty().predicates();
+        if let hir::TyImplTraitExistential(item_id, _, _) = ty.node {
+            if self.get(item_id.id).is_some() {
+                // Reach the (potentially private) type and the API being exposed
+                self.reach(item_id.id).ty().predicates();
             }
         }
 
@@ -434,6 +440,10 @@
 
     fn ty(&mut self) -> &mut Self {
         let ty = self.ev.tcx.type_of(self.item_def_id);
+        self.walk_ty(ty)
+    }
+
+    fn walk_ty(&mut self, ty: Ty<'tcx>) -> &mut Self {
         ty.visit_with(self);
         if let ty::TyFnDef(def_id, _) = ty.sty {
             if def_id == self.item_def_id {
@@ -1544,6 +1554,8 @@
             hir::ItemUse(..) => {}
             // No subitems
             hir::ItemGlobalAsm(..) => {}
+            // Checked in visit_ty
+            hir::ItemExistential(..) => {}
             // Subitems of these items have inherited publicity
             hir::ItemConst(..) | hir::ItemStatic(..) | hir::ItemFn(..) |
             hir::ItemTy(..) => {
@@ -1642,13 +1654,14 @@
     }
 
     fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
-        if let hir::TyImplTraitExistential(..) = ty.node {
+        if let hir::TyImplTraitExistential(ref exist_item, _, _) = ty.node {
             // Check the traits being exposed, as they're separate,
             // e.g. `impl Iterator<Item=T>` has two predicates,
             // `X: Iterator` and `<X as Iterator>::Item == T`,
             // where `X` is the `impl Iterator<Item=T>` itself,
             // stored in `predicates_of`, not in the `Ty` itself.
-            self.check(ty.id, self.inner_visibility).predicates();
+
+            self.check(exist_item.id, self.inner_visibility).predicates();
         }
 
         intravisit::walk_ty(self, ty);
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 2683a99..af7678a 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -118,7 +118,7 @@
             .collect();
 
         match use_tree.kind {
-            ast::UseTreeKind::Simple(rename) => {
+            ast::UseTreeKind::Simple(rename, ..) => {
                 let mut ident = use_tree.ident();
                 let mut source = module_path.pop().unwrap();
                 let mut type_ns_only = false;
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index 232a32d..5373333 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -967,16 +967,18 @@
 "##,
 
 E0423: r##"
-A `struct` variant name was used like a function name.
+An identifier was used like a function name or a value was expected and the
+identifier exists but it belongs to a different namespace.
 
-Erroneous code example:
+For (an erroneous) example, here a `struct` variant name were used as a
+function:
 
 ```compile_fail,E0423
 struct Foo { a: bool };
 
 let f = Foo();
-// error: `Foo` is a struct variant name, but this expression uses
-//        it like a function name
+// error: expected function, found `Foo`
+// `Foo` is a struct name, but this expression uses it like a function name
 ```
 
 Please verify you didn't misspell the name of what you actually wanted to use
@@ -987,6 +989,30 @@
 
 let f = Foo(); // ok!
 ```
+
+It is common to forget the trailing `!` on macro invocations, which would also
+yield this error:
+
+```compile_fail,E0423
+println("");
+// error: expected function, found macro `println`
+// did you mean `println!(...)`? (notice the trailing `!`)
+```
+
+Another case where this error is emitted is when a value is expected, but
+something else is found:
+
+```compile_fail,E0423
+pub mod a {
+    pub const I: i32 = 1;
+}
+
+fn h1() -> i32 {
+    a.I
+    //~^ ERROR expected value, found module `a`
+    // did you mean `a::I`?
+}
+```
 "##,
 
 E0424: r##"
@@ -1555,7 +1581,7 @@
                                             // `SomeModule` module.
 }
 
-println!("const value: {}", SomeModule::PRIVATE); // error: constant `CONSTANT`
+println!("const value: {}", SomeModule::PRIVATE); // error: constant `PRIVATE`
                                                   //        is private
 ```
 
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 453627f..a2b2096 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -27,7 +27,8 @@
 extern crate rustc;
 extern crate rustc_data_structures;
 
-use self::Namespace::*;
+pub use rustc::hir::def::{Namespace, PerNS};
+
 use self::TypeParameters::*;
 use self::RibKind::*;
 
@@ -37,6 +38,7 @@
 use rustc::session::Session;
 use rustc::lint;
 use rustc::hir::def::*;
+use rustc::hir::def::Namespace::*;
 use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
 use rustc::ty;
 use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
@@ -203,6 +205,7 @@
                 Def::AssociatedTy(..) | Def::PrimTy(..) | Def::Fn(..) | Def::Const(..) |
                 Def::Static(..) | Def::StructCtor(..) | Def::VariantCtor(..) | Def::Method(..) |
                 Def::AssociatedConst(..) | Def::Local(..) | Def::Upvar(..) | Def::Label(..) |
+                Def::Existential(..) |
                 Def::Macro(..) | Def::GlobalAsm(..) | Def::Err =>
                     bug!("TypeParametersFromOuterFunction should only be used with Def::SelfTy or \
                          Def::TyParam")
@@ -614,45 +617,6 @@
     }
 }
 
-/// Different kinds of symbols don't influence each other.
-///
-/// Therefore, they have a separate universe (namespace).
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
-pub enum Namespace {
-    TypeNS,
-    ValueNS,
-    MacroNS,
-}
-
-/// Just a helper ‒ separate structure for each namespace.
-#[derive(Clone, Default, Debug)]
-pub struct PerNS<T> {
-    value_ns: T,
-    type_ns: T,
-    macro_ns: T,
-}
-
-impl<T> ::std::ops::Index<Namespace> for PerNS<T> {
-    type Output = T;
-    fn index(&self, ns: Namespace) -> &T {
-        match ns {
-            ValueNS => &self.value_ns,
-            TypeNS => &self.type_ns,
-            MacroNS => &self.macro_ns,
-        }
-    }
-}
-
-impl<T> ::std::ops::IndexMut<Namespace> for PerNS<T> {
-    fn index_mut(&mut self, ns: Namespace) -> &mut T {
-        match ns {
-            ValueNS => &mut self.value_ns,
-            TypeNS => &mut self.type_ns,
-            MacroNS => &mut self.macro_ns,
-        }
-    }
-}
-
 struct UsePlacementFinder {
     target_module: NodeId,
     span: Option<Span>,
@@ -1346,6 +1310,7 @@
     primitive_type_table: PrimitiveTypeTable,
 
     def_map: DefMap,
+    import_map: ImportMap,
     pub freevars: FreevarMap,
     freevars_seen: NodeMap<NodeMap<usize>>,
     pub export_map: ExportMap,
@@ -1437,6 +1402,9 @@
     current_type_ascription: Vec<Span>,
 
     injected_crate: Option<Module<'a>>,
+
+    /// Only supposed to be used by rustdoc, otherwise should be false.
+    pub ignore_extern_prelude_feature: bool,
 }
 
 /// Nothing really interesting here, it just provides memory for the rest of the crate.
@@ -1515,6 +1483,10 @@
         self.def_map.get(&id).cloned()
     }
 
+    fn get_import(&mut self, id: NodeId) -> PerNS<Option<PathResolution>> {
+        self.import_map.get(&id).cloned().unwrap_or_default()
+    }
+
     fn definitions(&mut self) -> &mut Definitions {
         &mut self.definitions
     }
@@ -1662,6 +1634,7 @@
             primitive_type_table: PrimitiveTypeTable::new(),
 
             def_map: NodeMap(),
+            import_map: NodeMap(),
             freevars: NodeMap(),
             freevars_seen: NodeMap(),
             export_map: FxHashMap(),
@@ -1718,6 +1691,7 @@
             unused_macros: FxHashSet(),
             current_type_ascription: Vec::new(),
             injected_crate: None,
+            ignore_extern_prelude_feature: false,
         }
     }
 
@@ -1891,7 +1865,8 @@
         if !module.no_implicit_prelude {
             // `record_used` means that we don't try to load crates during speculative resolution
             if record_used && ns == TypeNS && self.extern_prelude.contains(&ident.name) {
-                if !self.session.features_untracked().extern_prelude {
+                if !self.session.features_untracked().extern_prelude &&
+                   !self.ignore_extern_prelude_feature {
                     feature_err(&self.session.parse_sess, "extern_prelude",
                                 ident.span, GateIssue::Language,
                                 "access to extern crates through prelude is experimental").emit();
@@ -2210,7 +2185,7 @@
                     }
                 }
             }
-            ast::UseTreeKind::Simple(_) => {},
+            ast::UseTreeKind::Simple(..) => {},
             ast::UseTreeKind::Glob => {},
         }
     }
@@ -2934,8 +2909,38 @@
                                                               here due to private fields"));
                             }
                         } else {
-                            err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?",
-                                                         path_str));
+                            // HACK(estebank): find a better way to figure out that this was a
+                            // parser issue where a struct literal is being used on an expression
+                            // where a brace being opened means a block is being started. Look
+                            // ahead for the next text to see if `span` is followed by a `{`.
+                            let cm = this.session.codemap();
+                            let mut sp = span;
+                            loop {
+                                sp = cm.next_point(sp);
+                                match cm.span_to_snippet(sp) {
+                                    Ok(ref snippet) => {
+                                        if snippet.chars().any(|c| { !c.is_whitespace() }) {
+                                            break;
+                                        }
+                                    }
+                                    _ => break,
+                                }
+                            }
+                            let followed_by_brace = match cm.span_to_snippet(sp) {
+                                Ok(ref snippet) if snippet == "{" => true,
+                                _ => false,
+                            };
+                            if let (PathSource::Expr(None), true) = (source, followed_by_brace) {
+                                err.span_label(
+                                    span,
+                                    format!("did you mean `({} {{ /* fields */ }})`?", path_str),
+                                );
+                            } else {
+                                err.span_label(
+                                    span,
+                                    format!("did you mean `{} {{ /* fields */ }}`?", path_str),
+                                );
+                            }
                         }
                         return (err, candidates);
                     }
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 0cc59e3..de7a3dc 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -138,7 +138,23 @@
         struct EliminateCrateVar<'b, 'a: 'b>(&'b mut Resolver<'a>, Span);
 
         impl<'a, 'b> Folder for EliminateCrateVar<'a, 'b> {
-            fn fold_path(&mut self, mut path: ast::Path) -> ast::Path {
+            fn fold_path(&mut self, path: ast::Path) -> ast::Path {
+                match self.fold_qpath(None, path) {
+                    (None, path) => path,
+                    _ => unreachable!(),
+                }
+            }
+
+            fn fold_qpath(&mut self, mut qself: Option<ast::QSelf>, mut path: ast::Path)
+                          -> (Option<ast::QSelf>, ast::Path) {
+                qself = qself.map(|ast::QSelf { ty, path_span, position }| {
+                    ast::QSelf {
+                        ty: self.fold_ty(ty),
+                        path_span: self.new_span(path_span),
+                        position,
+                    }
+                });
+
                 let ident = path.segments[0].ident;
                 if ident.name == keywords::DollarCrate.name() {
                     path.segments[0].ident.name = keywords::CrateRoot.name();
@@ -150,10 +166,13 @@
                                 ast::Ident::with_empty_ctxt(name).with_span_pos(span)
                             ),
                             _ => unreachable!(),
-                        })
+                        });
+                        if let Some(qself) = &mut qself {
+                            qself.position += 1;
+                        }
                     }
                 }
-                path
+                (qself, path)
             }
 
             fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
@@ -803,7 +822,6 @@
                     def: def,
                     vis: ty::Visibility::Public,
                     span: item.span,
-                    is_import: false,
                 });
             } else {
                 self.unused_macros.insert(def_id);
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 34f8459..8ac5e24 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -18,13 +18,14 @@
 use {resolve_error, ResolutionError};
 
 use rustc::ty;
-use rustc::lint::builtin::PUB_USE_OF_PRIVATE_EXTERN_CRATE;
+use rustc::lint::builtin::BuiltinLintDiagnostics;
+use rustc::lint::builtin::{DUPLICATE_MACRO_EXPORTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE};
 use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
 use rustc::hir::def::*;
 use rustc::session::DiagnosticMessageId;
 use rustc::util::nodemap::{FxHashMap, FxHashSet};
 
-use syntax::ast::{Ident, Name, NodeId};
+use syntax::ast::{Ident, Name, NodeId, CRATE_NODE_ID};
 use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
 use syntax::ext::hygiene::Mark;
 use syntax::symbol::keywords;
@@ -917,7 +918,8 @@
         // this may resolve to either a value or a type, but for documentation
         // purposes it's good enough to just favor one over the other.
         self.per_ns(|this, ns| if let Some(binding) = result[ns].get().ok() {
-            this.def_map.entry(directive.id).or_insert(PathResolution::new(binding.def()));
+            let mut import = this.import_map.entry(directive.id).or_default();
+            import[ns] = Some(PathResolution::new(binding.def()));
         });
 
         debug!("(resolving single import) successfully resolved import");
@@ -974,7 +976,16 @@
         if module as *const _ == self.graph_root as *const _ {
             let macro_exports = mem::replace(&mut self.macro_exports, Vec::new());
             for export in macro_exports.into_iter().rev() {
-                if exported_macro_names.insert(export.ident.modern(), export.span).is_none() {
+                if let Some(later_span) = exported_macro_names.insert(export.ident.modern(),
+                                                                      export.span) {
+                    self.session.buffer_lint_with_diagnostic(
+                        DUPLICATE_MACRO_EXPORTS,
+                        CRATE_NODE_ID,
+                        later_span,
+                        &format!("a macro named `{}` has already been exported", export.ident),
+                        BuiltinLintDiagnostics::DuplicatedMacroExports(
+                            export.ident, export.span, later_span));
+                } else {
                     reexports.push(export);
                 }
             }
@@ -1008,7 +1019,6 @@
                         def: def,
                         span: binding.span,
                         vis: binding.vis,
-                        is_import: true,
                     });
                 }
             }
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index e57a793..f951097 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -15,6 +15,8 @@
 #![cfg_attr(stage0, feature(macro_lifetime_matcher))]
 #![allow(unused_attributes)]
 
+#![recursion_limit="256"]
+
 #[macro_use]
 extern crate rustc;
 
@@ -747,6 +749,7 @@
             HirDef::TraitAlias(def_id) |
             HirDef::AssociatedTy(def_id) |
             HirDef::Trait(def_id) |
+            HirDef::Existential(def_id) |
             HirDef::TyParam(def_id) => {
                 let span = self.span_from_span(sub_span);
                 Some(Ref {
diff --git a/src/librustc_target/spec/linux_musl_base.rs b/src/librustc_target/spec/linux_musl_base.rs
index 293f23e..7a3f3c2 100644
--- a/src/librustc_target/spec/linux_musl_base.rs
+++ b/src/librustc_target/spec/linux_musl_base.rs
@@ -15,7 +15,8 @@
 
     // Make sure that the linker/gcc really don't pull in anything, including
     // default objects, libs, etc.
-    base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-nostdlib".to_string());
+    base.pre_link_args_crt.insert(LinkerFlavor::Gcc, Vec::new());
+    base.pre_link_args_crt.get_mut(&LinkerFlavor::Gcc).unwrap().push("-nostdlib".to_string());
 
     // At least when this was tested, the linker would not add the
     // `GNU_EH_FRAME` program header to executables generated, which is required
@@ -55,9 +56,9 @@
     //
     // Each target directory for musl has these object files included in it so
     // they'll be included from there.
-    base.pre_link_objects_exe.push("crt1.o".to_string());
-    base.pre_link_objects_exe.push("crti.o".to_string());
-    base.post_link_objects.push("crtn.o".to_string());
+    base.pre_link_objects_exe_crt.push("crt1.o".to_string());
+    base.pre_link_objects_exe_crt.push("crti.o".to_string());
+    base.post_link_objects_crt.push("crtn.o".to_string());
 
     // These targets statically link libc by default
     base.crt_static_default = true;
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index a0cbfe2..e54cd77 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -426,12 +426,13 @@
     /// Linker to invoke
     pub linker: Option<String>,
 
-    /// Linker arguments that are unconditionally passed *before* any
-    /// user-defined libraries.
-    pub pre_link_args: LinkArgs,
+    /// Linker arguments that are passed *before* any user-defined libraries.
+    pub pre_link_args: LinkArgs, // ... unconditionally
+    pub pre_link_args_crt: LinkArgs, // ... when linking with a bundled crt
     /// Objects to link before all others, always found within the
     /// sysroot folder.
-    pub pre_link_objects_exe: Vec<String>, // ... when linking an executable
+    pub pre_link_objects_exe: Vec<String>, // ... when linking an executable, unconditionally
+    pub pre_link_objects_exe_crt: Vec<String>, // ... when linking an executable with a bundled crt
     pub pre_link_objects_dll: Vec<String>, // ... when linking a dylib
     /// Linker arguments that are unconditionally passed after any
     /// user-defined but before post_link_objects.  Standard platform
@@ -439,7 +440,8 @@
     pub late_link_args: LinkArgs,
     /// Objects to link after all others, always found within the
     /// sysroot folder.
-    pub post_link_objects: Vec<String>,
+    pub post_link_objects: Vec<String>, // ... unconditionally
+    pub post_link_objects_crt: Vec<String>, // ... when linking with a bundled crt
     /// Linker arguments that are unconditionally passed *after* any
     /// user-defined libraries.
     pub post_link_args: LinkArgs,
@@ -639,6 +641,7 @@
             is_builtin: false,
             linker: option_env!("CFG_DEFAULT_LINKER").map(|s| s.to_string()),
             pre_link_args: LinkArgs::new(),
+            pre_link_args_crt: LinkArgs::new(),
             post_link_args: LinkArgs::new(),
             asm_args: Vec::new(),
             cpu: "generic".to_string(),
@@ -672,8 +675,10 @@
             position_independent_executables: false,
             relro_level: RelroLevel::None,
             pre_link_objects_exe: Vec::new(),
+            pre_link_objects_exe_crt: Vec::new(),
             pre_link_objects_dll: Vec::new(),
             post_link_objects: Vec::new(),
+            post_link_objects_crt: Vec::new(),
             late_link_args: LinkArgs::new(),
             link_env: Vec::new(),
             archive_format: "gnu".to_string(),
@@ -892,10 +897,13 @@
         key!(is_builtin, bool);
         key!(linker, optional);
         key!(pre_link_args, link_args);
+        key!(pre_link_args_crt, link_args);
         key!(pre_link_objects_exe, list);
+        key!(pre_link_objects_exe_crt, list);
         key!(pre_link_objects_dll, list);
         key!(late_link_args, link_args);
         key!(post_link_objects, list);
+        key!(post_link_objects_crt, list);
         key!(post_link_args, link_args);
         key!(link_env, env);
         key!(asm_args, list);
@@ -1097,10 +1105,13 @@
         target_option_val!(is_builtin);
         target_option_val!(linker);
         target_option_val!(link_args - pre_link_args);
+        target_option_val!(link_args - pre_link_args_crt);
         target_option_val!(pre_link_objects_exe);
+        target_option_val!(pre_link_objects_exe_crt);
         target_option_val!(pre_link_objects_dll);
         target_option_val!(link_args - late_link_args);
         target_option_val!(post_link_objects);
+        target_option_val!(post_link_objects_crt);
         target_option_val!(link_args - post_link_args);
         target_option_val!(env - link_env);
         target_option_val!(asm_args);
diff --git a/src/librustc_traits/lib.rs b/src/librustc_traits/lib.rs
index 733d8e1..c313543 100644
--- a/src/librustc_traits/lib.rs
+++ b/src/librustc_traits/lib.rs
@@ -17,6 +17,8 @@
 #![feature(iterator_find_map)]
 #![feature(in_band_lifetimes)]
 
+#![recursion_limit="256"]
+
 extern crate chalk_engine;
 #[macro_use]
 extern crate log;
@@ -34,7 +36,7 @@
 mod util;
 pub mod lowering;
 
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 
 pub fn provide(p: &mut Providers) {
     *p = Providers {
diff --git a/src/librustc_tsan/lib.rs b/src/librustc_tsan/lib.rs
index 3429e3b..a7aeed7 100644
--- a/src/librustc_tsan/lib.rs
+++ b/src/librustc_tsan/lib.rs
@@ -10,8 +10,7 @@
 
 #![sanitizer_runtime]
 #![feature(alloc_system)]
-#![feature(allocator_api)]
-#![feature(global_allocator)]
+#![cfg_attr(stage0, feature(global_allocator))]
 #![feature(sanitizer_runtime)]
 #![feature(staged_api)]
 #![no_std]
diff --git a/src/librustc_typeck/Cargo.toml b/src/librustc_typeck/Cargo.toml
index c426533..184cb98 100644
--- a/src/librustc_typeck/Cargo.toml
+++ b/src/librustc_typeck/Cargo.toml
@@ -13,7 +13,6 @@
 log = "0.4"
 syntax = { path = "../libsyntax" }
 arena = { path = "../libarena" }
-fmt_macros = { path = "../libfmt_macros" }
 rustc = { path = "../librustc" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_platform_intrinsics = { path = "../librustc_platform_intrinsics" }
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 7ef510f..18911b4 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -646,7 +646,7 @@
                                             &mut vec![]);
         }
 
-        let (auto_traits, trait_bounds) = split_auto_traits(tcx, &trait_bounds[1..]);
+        let (mut auto_traits, trait_bounds) = split_auto_traits(tcx, &trait_bounds[1..]);
 
         if !trait_bounds.is_empty() {
             let b = &trait_bounds[0];
@@ -707,6 +707,10 @@
                         .emit();
         }
 
+        // Dedup auto traits so that `dyn Trait + Send + Send` is the same as `dyn Trait + Send`.
+        auto_traits.sort();
+        auto_traits.dedup();
+
         // skip_binder is okay, because the predicates are re-bound.
         let mut v =
             iter::once(ty::ExistentialPredicate::Trait(*existential_principal.skip_binder()))
@@ -714,7 +718,7 @@
             .chain(existential_projections
                    .map(|x| ty::ExistentialPredicate::Projection(*x.skip_binder())))
             .collect::<AccumulateVec<[_; 8]>>();
-        v.sort_by(|a, b| a.cmp(tcx, b));
+        v.sort_by(|a, b| a.stable_cmp(tcx, b));
         let existential_predicates = ty::Binder::bind(tcx.mk_existential_predicates(v.into_iter()));
 
 
@@ -1114,8 +1118,7 @@
             hir::TyTraitObject(ref bounds, ref lifetime) => {
                 self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime)
             }
-            hir::TyImplTraitExistential(_, ref lifetimes) => {
-                let def_id = tcx.hir.local_def_id(ast_ty.id);
+            hir::TyImplTraitExistential(_, def_id, ref lifetimes) => {
                 self.impl_trait_ty_to_ty(def_id, lifetimes)
             }
             hir::TyPath(hir::QPath::Resolved(ref maybe_qself, ref path)) => {
@@ -1167,9 +1170,14 @@
         result_ty
     }
 
-    pub fn impl_trait_ty_to_ty(&self, def_id: DefId, lifetimes: &[hir::Lifetime]) -> Ty<'tcx> {
+    pub fn impl_trait_ty_to_ty(
+        &self,
+        def_id: DefId,
+        lifetimes: &[hir::Lifetime],
+    ) -> Ty<'tcx> {
         debug!("impl_trait_ty_to_ty(def_id={:?}, lifetimes={:?})", def_id, lifetimes);
         let tcx = self.tcx();
+
         let generics = tcx.generics_of(def_id);
 
         debug!("impl_trait_ty_to_ty: generics={:?}", generics);
@@ -1194,7 +1202,9 @@
         });
         debug!("impl_trait_ty_to_ty: final substs = {:?}", substs);
 
-        tcx.mk_anon(def_id, substs)
+        let ty = tcx.mk_anon(def_id, substs);
+        debug!("impl_trait_ty_to_ty: {}", ty);
+        ty
     }
 
     pub fn ty_of_arg(&self,
@@ -1319,7 +1329,7 @@
     }
 }
 
-/// Divides a list of general trait bounds into two groups: builtin bounds (Sync/Send) and the
+/// Divides a list of general trait bounds into two groups: auto traits (e.g. Sync and Send) and the
 /// remaining general trait bounds.
 fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
                                          trait_bounds: &'b [hir::PolyTraitRef])
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index 67245be..cfe9e42 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -225,7 +225,6 @@
         let expected_sig = fulfillment_cx
             .pending_obligations()
             .iter()
-            .map(|obligation| &obligation.obligation)
             .filter_map(|obligation| {
                 debug!(
                     "deduce_expectations_from_obligations: obligation.predicate={:?}",
@@ -257,7 +256,6 @@
         let expected_kind = fulfillment_cx
             .pending_obligations()
             .iter()
-            .map(|obligation| &obligation.obligation)
             .filter_map(|obligation| {
                 let opt_trait_ref = match obligation.predicate {
                     ty::Predicate::Projection(ref data) => Some(data.to_poly_trait_ref(self.tcx)),
@@ -465,7 +463,7 @@
         // Create a `PolyFnSig`. Note the oddity that late bound
         // regions appearing free in `expected_sig` are now bound up
         // in this binder we are creating.
-        assert!(!expected_sig.sig.has_regions_bound_above(ty::DebruijnIndex::INNERMOST));
+        assert!(!expected_sig.sig.has_regions_bound_above(ty::INNERMOST));
         let bound_sig = ty::Binder::bind(self.tcx.mk_fn_sig(
             expected_sig.sig.inputs().iter().cloned(),
             expected_sig.sig.output(),
diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs
index e234e2f..e209049 100644
--- a/src/librustc_typeck/check/generator_interior.rs
+++ b/src/librustc_typeck/check/generator_interior.rs
@@ -65,7 +65,7 @@
                    expr, scope, ty, self.expr_count, yield_span);
 
             if self.fcx.any_unresolved_type_vars(&ty) {
-                let mut err = struct_span_err!(self.fcx.tcx.sess, source_span, E0907,
+                let mut err = struct_span_err!(self.fcx.tcx.sess, source_span, E0698,
                     "type inside generator must be known in this context");
                 err.span_note(yield_span,
                               "the type is part of the generator because of this `yield`");
diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs
index 215a316..c93023e 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/src/librustc_typeck/check/intrinsic.rs
@@ -119,7 +119,7 @@
             "pref_align_of" | "min_align_of" => (1, Vec::new(), tcx.types.usize),
             "size_of_val" |  "min_align_of_val" => {
                 (1, vec![
-                    tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::INNERMOST,
+                    tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::INNERMOST,
                                                                   ty::BrAnon(0))),
                                     param(0))
                  ], tcx.types.usize)
@@ -298,7 +298,7 @@
             "unlikely" => (0, vec![tcx.types.bool], tcx.types.bool),
 
             "discriminant_value" => (1, vec![
-                    tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::DebruijnIndex::INNERMOST,
+                    tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::INNERMOST,
                                                                   ty::BrAnon(0))),
                                    param(0))], tcx.types.u64),
 
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index 169caf1..a51876d 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -40,7 +40,7 @@
 
 use self::probe::{IsSuggestion, ProbeScope};
 
-pub fn provide(providers: &mut ty::maps::Providers) {
+pub fn provide(providers: &mut ty::query::Providers) {
     suggest::provide(providers);
 }
 
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 7c51765..834c7d4 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -335,7 +335,7 @@
                         // so we do a future-compat lint here for the 2015 edition
                         // (see https://github.com/rust-lang/rust/issues/46906)
                         if self.tcx.sess.rust_2018() {
-                          span_err!(self.tcx.sess, span, E0908,
+                          span_err!(self.tcx.sess, span, E0699,
                                     "the type of this value must be known \
                                      to call a method on a raw pointer on it");
                         } else {
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 8a575c1..90680b4 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -119,11 +119,16 @@
                             }
                         };
 
-                        let note_str = format!("candidate #{} is defined in an impl{} \
-                                                for the type `{}`",
-                                               idx + 1,
-                                               insertion,
-                                               impl_ty);
+                        let note_str = if sources.len() > 1 {
+                            format!("candidate #{} is defined in an impl{} for the type `{}`",
+                                    idx + 1,
+                                    insertion,
+                                    impl_ty)
+                        } else {
+                            format!("the candidate is defined in an impl{} for the type `{}`",
+                                    insertion,
+                                    impl_ty)
+                        };
                         if let Some(note_span) = note_span {
                             // We have a span pointing to the method. Show note with snippet.
                             err.span_note(self.tcx.sess.codemap().def_span(note_span), &note_str);
@@ -137,11 +142,18 @@
                             .unwrap();
                         let item_span = self.tcx.sess.codemap()
                             .def_span(self.tcx.def_span(item.def_id));
-                        span_note!(err,
-                                   item_span,
-                                   "candidate #{} is defined in the trait `{}`",
-                                   idx + 1,
-                                   self.tcx.item_path_str(trait_did));
+                        if sources.len() > 1 {
+                            span_note!(err,
+                                       item_span,
+                                       "candidate #{} is defined in the trait `{}`",
+                                       idx + 1,
+                                       self.tcx.item_path_str(trait_did));
+                        } else {
+                            span_note!(err,
+                                       item_span,
+                                       "the candidate is defined in the trait `{}`",
+                                       self.tcx.item_path_str(trait_did));
+                        }
                         err.help(&format!("to disambiguate the method call, write `{}::{}({}{})` \
                                           instead",
                                           self.tcx.item_path_str(trait_did),
@@ -183,7 +195,7 @@
                 let ty_string = self.ty_to_string(actual);
                 let is_method = mode == Mode::MethodCall;
                 let mut suggestion = None;
-                let type_str = if is_method {
+                let item_kind = if is_method {
                     "method"
                 } else if actual.is_enum() {
                     if let TyAdt(ref adt_def, _) = actual.sty {
@@ -223,7 +235,7 @@
                             span,
                             E0689,
                             "can't call {} `{}` on ambiguous numeric type `{}`",
-                            type_str,
+                            item_kind,
                             item_name,
                             ty_string
                         );
@@ -272,12 +284,12 @@
                             span,
                             E0599,
                             "no {} named `{}` found for type `{}` in the current scope",
-                            type_str,
+                            item_kind,
                             item_name,
                             ty_string
                         );
                         if let Some(suggestion) = suggestion {
-                            err.note(&format!("did you mean `{}::{}`?", type_str, suggestion));
+                            err.note(&format!("did you mean `{}::{}`?", ty_string, suggestion));
                         }
                         err
                     }
@@ -285,11 +297,11 @@
                     tcx.sess.diagnostic().struct_dummy()
                 };
 
-                if let Some(def) =  actual.ty_adt_def() {
+                if let Some(def) = actual.ty_adt_def() {
                     if let Some(full_sp) = tcx.hir.span_if_local(def.did) {
                         let def_sp = tcx.sess.codemap().def_span(full_sp);
                         err.span_label(def_sp, format!("{} `{}` not found {}",
-                                                       type_str,
+                                                       item_kind,
                                                        item_name,
                                                        if def.is_enum() && !is_method {
                                                            "here"
@@ -343,7 +355,7 @@
                         }
                     }
                 } else {
-                    err.span_label(span, format!("{} not found in `{}`", type_str, ty_string));
+                    err.span_label(span, format!("{} not found in `{}`", item_kind, ty_string));
                 }
 
                 if self.is_fn_ty(&rcvr_ty, span) {
@@ -368,7 +380,22 @@
                 if !static_sources.is_empty() {
                     err.note("found the following associated functions; to be used as methods, \
                               functions must have a `self` parameter");
-                    err.help(&format!("try with `{}::{}`", self.ty_to_string(actual), item_name));
+                    err.span_label(span, "this is an associated function, not a method");
+                }
+                if static_sources.len() == 1 {
+                    if let Some(expr) = rcvr_expr {
+                        err.span_suggestion(expr.span.to(span),
+                                            "use associated function syntax instead",
+                                            format!("{}::{}",
+                                                    self.ty_to_string(actual),
+                                                    item_name));
+                    } else {
+                        err.help(&format!("try with `{}::{}`",
+                                          self.ty_to_string(actual), item_name));
+                    }
+
+                    report_candidates(&mut err, static_sources);
+                } else if static_sources.len() > 1 {
 
                     report_candidates(&mut err, static_sources);
                 }
@@ -468,9 +495,14 @@
         } else {
             let limit = if candidates.len() == 5 { 5 } else { 4 };
             for (i, trait_did) in candidates.iter().take(limit).enumerate() {
-                msg.push_str(&format!("\ncandidate #{}: `use {};`",
-                                        i + 1,
-                                        self.tcx.item_path_str(*trait_did)));
+                if candidates.len() > 1 {
+                    msg.push_str(&format!("\ncandidate #{}: `use {};`",
+                                            i + 1,
+                                            self.tcx.item_path_str(*trait_did)));
+                } else {
+                    msg.push_str(&format!("\n`use {};`",
+                                            self.tcx.item_path_str(*trait_did)));
+                }
             }
             if candidates.len() > limit {
                 msg.push_str(&format!("\nand {} others", candidates.len() - limit));
@@ -709,7 +741,7 @@
     traits
 }
 
-pub fn provide(providers: &mut ty::maps::Providers) {
+pub fn provide(providers: &mut ty::query::Providers) {
     providers.all_traits = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
         Lrc::new(compute_all_traits(tcx))
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 90b974f..d68fc67 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -96,10 +96,10 @@
 use rustc::mir::interpret::{GlobalId};
 use rustc::ty::subst::{UnpackedKind, Subst, Substs};
 use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
-use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind, Visibility, ToPredicate};
+use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind, Visibility, ToPredicate, RegionKind};
 use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
 use rustc::ty::fold::TypeFoldable;
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::ty::util::{Representability, IntTypeExt, Discr};
 use errors::{DiagnosticBuilder, DiagnosticId};
 
@@ -130,7 +130,7 @@
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::hir::map::Node;
-use rustc::hir::{self, PatKind};
+use rustc::hir::{self, PatKind, Item_};
 use rustc::middle::lang_items;
 
 mod autoderef;
@@ -703,7 +703,7 @@
     debug_assert!(crate_num == LOCAL_CRATE);
     Ok(tcx.sess.track_errors(|| {
         for body_owner_def_id in tcx.body_owners() {
-            ty::maps::queries::typeck_tables_of::ensure(tcx, body_owner_def_id);
+            ty::query::queries::typeck_tables_of::ensure(tcx, body_owner_def_id);
         }
     })?)
 }
@@ -1013,7 +1013,7 @@
     debug!("check_fn(sig={:?}, fn_id={}, param_env={:?})", fn_sig, fn_id, param_env);
 
     // Create the function context.  This is either derived from scratch or,
-    // in the case of function expressions, based on the outer context.
+    // in the case of closures, based on the outer context.
     let mut fcx = FnCtxt::new(inherited, param_env, body.value.id);
     *fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
 
@@ -1129,6 +1129,60 @@
         }
     }
 
+    // Check that a function marked as `#[panic_implementation]` has signature `fn(&PanicInfo) -> !`
+    if let Some(panic_impl_did) = fcx.tcx.lang_items().panic_impl() {
+        if panic_impl_did == fcx.tcx.hir.local_def_id(fn_id) {
+            if let Some(panic_info_did) = fcx.tcx.lang_items().panic_info() {
+                if declared_ret_ty.sty != ty::TyNever {
+                    fcx.tcx.sess.span_err(
+                        decl.output.span(),
+                        "return type should be `!`",
+                    );
+                }
+
+                let inputs = fn_sig.inputs();
+                let span = fcx.tcx.hir.span(fn_id);
+                if inputs.len() == 1 {
+                    let arg_is_panic_info = match inputs[0].sty {
+                        ty::TyRef(region, ty, mutbl) => match ty.sty {
+                            ty::TyAdt(ref adt, _) => {
+                                adt.did == panic_info_did &&
+                                    mutbl == hir::Mutability::MutImmutable &&
+                                    *region != RegionKind::ReStatic
+                            },
+                            _ => false,
+                        },
+                        _ => false,
+                    };
+
+                    if !arg_is_panic_info {
+                        fcx.tcx.sess.span_err(
+                            decl.inputs[0].span,
+                            "argument should be `&PanicInfo`",
+                        );
+                    }
+
+                    if let Node::NodeItem(item) = fcx.tcx.hir.get(fn_id) {
+                        if let Item_::ItemFn(_, _, _, _, ref generics, _) = item.node {
+                            if !generics.params.is_empty() {
+                                fcx.tcx.sess.span_err(
+                                    span,
+                                    "`#[panic_implementation]` function should have no type \
+                                     parameters",
+                                );
+                            }
+                        }
+                    }
+                } else {
+                    fcx.tcx.sess.span_err(span, "function should have one argument");
+                }
+            } else {
+                fcx.tcx.sess.err("language item required, but not found: `panic_info`");
+            }
+        }
+
+    }
+
     (fcx, gen_ty)
 }
 
@@ -3986,7 +4040,10 @@
             let count = tcx.const_eval(param_env.and(global_id));
 
             if let Err(ref err) = count {
-                err.report(tcx, tcx.def_span(count_def_id), "constant expression");
+                err.report_as_error(
+                    tcx.at(tcx.def_span(count_def_id)),
+                    "could not evaluate repeat length",
+                );
             }
 
             let uty = match expected {
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index 4b4b982..7a2c384 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -711,6 +711,7 @@
     for pred in implied_obligations {
         // Match the existing behavior.
         if pred.is_global() && !pred.has_late_bound_regions() {
+            let pred = fcx.normalize_associated_types_in(span, &pred);
             let obligation = traits::Obligation::new(
                 traits::ObligationCause::new(
                     span,
@@ -748,21 +749,21 @@
     fn visit_item(&mut self, i: &hir::Item) {
         debug!("visit_item: {:?}", i);
         let def_id = self.tcx.hir.local_def_id(i.id);
-        ty::maps::queries::check_item_well_formed::ensure(self.tcx, def_id);
+        ty::query::queries::check_item_well_formed::ensure(self.tcx, def_id);
         intravisit::walk_item(self, i);
     }
 
     fn visit_trait_item(&mut self, trait_item: &'v hir::TraitItem) {
         debug!("visit_trait_item: {:?}", trait_item);
         let def_id = self.tcx.hir.local_def_id(trait_item.id);
-        ty::maps::queries::check_trait_item_well_formed::ensure(self.tcx, def_id);
+        ty::query::queries::check_trait_item_well_formed::ensure(self.tcx, def_id);
         intravisit::walk_trait_item(self, trait_item)
     }
 
     fn visit_impl_item(&mut self, impl_item: &'v hir::ImplItem) {
         debug!("visit_impl_item: {:?}", impl_item);
         let def_id = self.tcx.hir.local_def_id(impl_item.id);
-        ty::maps::queries::check_impl_item_well_formed::ensure(self.tcx, def_id);
+        ty::query::queries::check_impl_item_well_formed::ensure(self.tcx, def_id);
         intravisit::walk_impl_item(self, impl_item)
     }
 }
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index f295d17..f7d1e40 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -43,7 +43,7 @@
         wbcx.visit_closures();
         wbcx.visit_liberated_fn_sigs();
         wbcx.visit_fru_field_types();
-        wbcx.visit_anon_types();
+        wbcx.visit_anon_types(body.value.span);
         wbcx.visit_cast_types();
         wbcx.visit_free_region_map();
         wbcx.visit_user_provided_tys();
@@ -385,18 +385,28 @@
         }
     }
 
-    fn visit_anon_types(&mut self) {
-        let gcx = self.tcx().global_tcx();
+    fn visit_anon_types(&mut self, span: Span) {
         for (&def_id, anon_defn) in self.fcx.anon_types.borrow().iter() {
-            let node_id = gcx.hir.as_local_node_id(def_id).unwrap();
+            let node_id = self.tcx().hir.as_local_node_id(def_id).unwrap();
             let instantiated_ty = self.resolve(&anon_defn.concrete_ty, &node_id);
             let definition_ty = self.fcx.infer_anon_definition_from_instantiation(
                 def_id,
                 anon_defn,
                 instantiated_ty,
             );
-            let hir_id = self.tcx().hir.node_to_hir_id(node_id);
-            self.tables.node_types_mut().insert(hir_id, definition_ty);
+            let old = self.tables.concrete_existential_types.insert(def_id, definition_ty);
+            if let Some(old) = old {
+                if old != definition_ty {
+                    span_bug!(
+                        span,
+                        "visit_anon_types tried to write \
+                        different types for the same existential type: {:?}, {:?}, {:?}",
+                        def_id,
+                        definition_ty,
+                        old,
+                    );
+                }
+            }
         }
     }
 
diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs
index bff849d..41adde0 100644
--- a/src/librustc_typeck/check_unused.rs
+++ b/src/librustc_typeck/check_unused.rs
@@ -14,11 +14,46 @@
 use syntax::ast;
 use syntax_pos::{Span, DUMMY_SP};
 
-use rustc::hir::def_id::LOCAL_CRATE;
+use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
+use rustc::hir::print::visibility_qualified;
 use rustc::hir;
 use rustc::util::nodemap::DefIdSet;
 
+use rustc_data_structures::fx::FxHashMap;
+
+pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
+    let mut used_trait_imports = DefIdSet();
+    for &body_id in tcx.hir.krate().bodies.keys() {
+        let item_def_id = tcx.hir.body_owner_def_id(body_id);
+        let imports = tcx.used_trait_imports(item_def_id);
+        debug!("GatherVisitor: item_def_id={:?} with imports {:#?}", item_def_id, imports);
+        used_trait_imports.extend(imports.iter());
+    }
+
+    let mut visitor = CheckVisitor { tcx, used_trait_imports };
+    tcx.hir.krate().visit_all_item_likes(&mut visitor);
+
+    unused_crates_lint(tcx);
+}
+
+impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for CheckVisitor<'a, 'tcx> {
+    fn visit_item(&mut self, item: &hir::Item) {
+        if item.vis == hir::Public || item.span == DUMMY_SP {
+            return;
+        }
+        if let hir::ItemUse(ref path, _) = item.node {
+            self.check_import(item.id, path.span);
+        }
+    }
+
+    fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
+    }
+
+    fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
+    }
+}
+
 struct CheckVisitor<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     used_trait_imports: DefIdSet,
@@ -45,13 +80,131 @@
     }
 }
 
-impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for CheckVisitor<'a, 'tcx> {
-    fn visit_item(&mut self, item: &hir::Item) {
-        if item.vis == hir::Public || item.span == DUMMY_SP {
-            return;
+fn unused_crates_lint<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) {
+    let lint = lint::builtin::UNUSED_EXTERN_CRATES;
+
+    // Collect first the crates that are completely unused.  These we
+    // can always suggest removing (no matter which edition we are
+    // in).
+    let unused_extern_crates: FxHashMap<DefId, Span> =
+        tcx.maybe_unused_extern_crates(LOCAL_CRATE)
+        .iter()
+        .filter(|&&(def_id, _)| {
+            // The `def_id` here actually was calculated during resolution (at least
+            // at the time of this writing) and is being shipped to us via a side
+            // channel of the tcx. There may have been extra expansion phases,
+            // however, which ended up removing the `def_id` *after* expansion such
+            // as the `ReplaceBodyWithLoop` pass (which is a bit of a hack, but hey)
+            //
+            // As a result we need to verify that `def_id` is indeed still valid for
+            // our AST and actually present in the HIR map. If it's not there then
+            // there's safely nothing to warn about, and otherwise we carry on with
+            // our execution.
+            //
+            // Note that if we carry through to the `extern_mod_stmt_cnum` query
+            // below it'll cause a panic because `def_id` is actually bogus at this
+            // point in time otherwise.
+            if let Some(id) = tcx.hir.as_local_node_id(def_id) {
+                if tcx.hir.find(id).is_none() {
+                    return false;
+                }
+            }
+            true
+        })
+        .filter(|&&(def_id, _)| {
+            let cnum = tcx.extern_mod_stmt_cnum(def_id).unwrap();
+            !tcx.is_compiler_builtins(cnum)
+                && !tcx.is_panic_runtime(cnum)
+                && !tcx.has_global_allocator(cnum)
+        })
+        .cloned()
+        .collect();
+
+    // Collect all the extern crates (in a reliable order).
+    let mut crates_to_lint = vec![];
+    tcx.hir.krate().visit_all_item_likes(&mut CollectExternCrateVisitor {
+        tcx,
+        crates_to_lint: &mut crates_to_lint,
+    });
+
+    for extern_crate in &crates_to_lint {
+        assert!(extern_crate.def_id.is_local());
+
+        // If the crate is fully unused, we suggest removing it altogether.
+        // We do this in any edition.
+        if let Some(&span) = unused_extern_crates.get(&extern_crate.def_id) {
+            assert_eq!(extern_crate.def_id.krate, LOCAL_CRATE);
+            let hir_id = tcx.hir.definitions().def_index_to_hir_id(extern_crate.def_id.index);
+            let id = tcx.hir.hir_to_node_id(hir_id);
+            let msg = "unused extern crate";
+            tcx.struct_span_lint_node(lint, id, span, msg)
+                .span_suggestion_short(span, "remove it", "".to_string())
+                .emit();
+            continue;
         }
-        if let hir::ItemUse(ref path, _) = item.node {
-            self.check_import(item.id, path.span);
+
+        // If we are not in Rust 2018 edition, then we don't make any further
+        // suggestions.
+        if !tcx.sess.rust_2018() {
+            continue;
+        }
+
+        // If the extern crate has any attributes, they may have funky
+        // semantics we can't faithfully represent using `use` (most
+        // notably `#[macro_use]`). Ignore it.
+        if !tcx.get_attrs(extern_crate.def_id).is_empty() {
+            continue;
+        }
+
+        // Otherwise, we can convert it into a `use` of some kind.
+        let hir_id = tcx.hir.definitions().def_index_to_hir_id(extern_crate.def_id.index);
+        let id = tcx.hir.hir_to_node_id(hir_id);
+        let item = tcx.hir.expect_item(id);
+        let msg = "`extern crate` is not idiomatic in the new edition";
+        let help = format!(
+            "convert it to a `{}`",
+            visibility_qualified(&item.vis, "use")
+        );
+        let base_replacement = match extern_crate.orig_name {
+            Some(orig_name) => format!("use {} as {};", orig_name, item.name),
+            None => format!("use {};", item.name),
+        };
+        let replacement = visibility_qualified(&item.vis, &base_replacement);
+        tcx.struct_span_lint_node(lint, id, extern_crate.span, msg)
+            .span_suggestion_short(extern_crate.span, &help, replacement)
+            .emit();
+    }
+}
+
+struct CollectExternCrateVisitor<'a, 'tcx: 'a> {
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    crates_to_lint: &'a mut Vec<ExternCrateToLint>,
+}
+
+struct ExternCrateToLint {
+    /// def-id of the extern crate
+    def_id: DefId,
+
+    /// span from the item
+    span: Span,
+
+    /// if `Some`, then this is renamed (`extern crate orig_name as
+    /// crate_name`), and -- perhaps surprisingly -- this stores the
+    /// *original* name (`item.name` will contain the new name)
+    orig_name: Option<ast::Name>,
+}
+
+impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for CollectExternCrateVisitor<'a, 'tcx> {
+    fn visit_item(&mut self, item: &hir::Item) {
+        if let hir::ItemExternCrate(orig_name) = item.node {
+            let extern_crate_def_id = self.tcx.hir.local_def_id(item.id);
+            self.crates_to_lint.push(
+                ExternCrateToLint {
+                    def_id: extern_crate_def_id,
+                    span: item.span,
+                    orig_name,
+                }
+            );
         }
     }
 
@@ -62,53 +215,3 @@
     }
 }
 
-pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
-    let mut used_trait_imports = DefIdSet();
-    for &body_id in tcx.hir.krate().bodies.keys() {
-        let item_def_id = tcx.hir.body_owner_def_id(body_id);
-        let imports = tcx.used_trait_imports(item_def_id);
-        debug!("GatherVisitor: item_def_id={:?} with imports {:#?}", item_def_id, imports);
-        used_trait_imports.extend(imports.iter());
-    }
-
-    let mut visitor = CheckVisitor { tcx, used_trait_imports };
-    tcx.hir.krate().visit_all_item_likes(&mut visitor);
-
-    for &(def_id, span) in tcx.maybe_unused_extern_crates(LOCAL_CRATE).iter() {
-        // The `def_id` here actually was calculated during resolution (at least
-        // at the time of this writing) and is being shipped to us via a side
-        // channel of the tcx. There may have been extra expansion phases,
-        // however, which ended up removing the `def_id` *after* expansion such
-        // as the `ReplaceBodyWithLoop` pass (which is a bit of a hack, but hey)
-        //
-        // As a result we need to verify that `def_id` is indeed still valid for
-        // our AST and actually present in the HIR map. If it's not there then
-        // there's safely nothing to warn about, and otherwise we carry on with
-        // our execution.
-        //
-        // Note that if we carry through to the `extern_mod_stmt_cnum` query
-        // below it'll cause a panic because `def_id` is actually bogus at this
-        // point in time otherwise.
-        if let Some(id) = tcx.hir.as_local_node_id(def_id) {
-            if tcx.hir.find(id).is_none() {
-                continue
-            }
-        }
-        let cnum = tcx.extern_mod_stmt_cnum(def_id).unwrap();
-        if tcx.is_compiler_builtins(cnum) {
-            continue
-        }
-        if tcx.is_panic_runtime(cnum) {
-            continue
-        }
-        if tcx.has_global_allocator(cnum) {
-            continue
-        }
-        assert_eq!(def_id.krate, LOCAL_CRATE);
-        let hir_id = tcx.hir.definitions().def_index_to_hir_id(def_id.index);
-        let id = tcx.hir.hir_to_node_id(hir_id);
-        let lint = lint::builtin::UNUSED_EXTERN_CRATES;
-        let msg = "unused extern crate";
-        tcx.lint_node(lint, id, span, msg);
-    }
-}
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index 07b7c60..e923490 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -18,7 +18,7 @@
 use hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::traits;
 use rustc::ty::{self, TyCtxt, TypeFoldable};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 
 use syntax::ast;
 
@@ -127,15 +127,15 @@
 
 pub fn check_coherence<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     for &trait_def_id in tcx.hir.krate().trait_impls.keys() {
-        ty::maps::queries::coherent_trait::ensure(tcx, trait_def_id);
+        ty::query::queries::coherent_trait::ensure(tcx, trait_def_id);
     }
 
     unsafety::check(tcx);
     orphan::check(tcx);
 
     // these queries are executed for side-effects (error reporting):
-    ty::maps::queries::crate_inherent_impls::ensure(tcx, LOCAL_CRATE);
-    ty::maps::queries::crate_inherent_impls_overlap_check::ensure(tcx, LOCAL_CRATE);
+    ty::query::queries::crate_inherent_impls::ensure(tcx, LOCAL_CRATE);
+    ty::query::queries::crate_inherent_impls_overlap_check::ensure(tcx, LOCAL_CRATE);
 }
 
 /// Overlap: No two impls for the same trait are implemented for the
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index a982724..58e804f 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -33,7 +33,7 @@
 use rustc::ty::subst::Substs;
 use rustc::ty::{ToPredicate, ReprOptions};
 use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::ty::util::IntTypeExt;
 use rustc::ty::util::Discr;
 use rustc::util::captures::Captures;
@@ -131,15 +131,6 @@
         intravisit::walk_expr(self, expr);
     }
 
-    fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
-        if let hir::TyImplTraitExistential(..) = ty.node {
-            let def_id = self.tcx.hir.local_def_id(ty.id);
-            self.tcx.generics_of(def_id);
-            self.tcx.predicates_of(def_id);
-        }
-        intravisit::walk_ty(self, ty);
-    }
-
     fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
         convert_trait_item(self.tcx, trait_item.id);
         intravisit::walk_trait_item(self, trait_item);
@@ -420,6 +411,7 @@
                 convert_variant_ctor(tcx, struct_def.id());
             }
         },
+        hir::ItemExistential(..) |
         hir::ItemTy(..) | hir::ItemStatic(..) | hir::ItemConst(..) | hir::ItemFn(..) => {
             tcx.generics_of(def_id);
             tcx.type_of(def_id);
@@ -744,7 +736,7 @@
                                         -> Option<Span> {
         let mut visitor = LateBoundRegionsDetector {
             tcx,
-            outer_index: ty::DebruijnIndex::INNERMOST,
+            outer_index: ty::INNERMOST,
             has_late_bound_regions: None,
         };
         for lifetime in generics.lifetimes() {
@@ -803,18 +795,12 @@
         NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
             Some(tcx.closure_base_def_id(def_id))
         }
-        NodeTy(&hir::Ty { node: hir::TyImplTraitExistential(..), .. }) => {
-            let mut parent_id = node_id;
-            loop {
-                match tcx.hir.get(parent_id) {
-                    NodeItem(_) | NodeImplItem(_) | NodeTraitItem(_) => break,
-                    _ => {
-                        parent_id = tcx.hir.get_parent_node(parent_id);
-                    }
-                }
+        NodeItem(item) => {
+            match item.node {
+                ItemExistential(hir::ExistTy { impl_trait_fn, .. }) => impl_trait_fn,
+                _ => None,
             }
-            Some(tcx.hir.local_def_id(parent_id))
-        }
+        },
         _ => None
     };
 
@@ -835,6 +821,7 @@
                 ItemTy(_, ref generics) |
                 ItemEnum(_, ref generics) |
                 ItemStruct(_, ref generics) |
+                ItemExistential(hir::ExistTy { ref generics, .. }) |
                 ItemUnion(_, ref generics) => {
                     allow_defaults = true;
                     generics
@@ -875,8 +862,8 @@
             }
         }
 
-        NodeTy(&hir::Ty { node: hir::TyImplTraitExistential(ref exist_ty, _), .. }) => {
-            &exist_ty.generics
+        NodeTy(&hir::Ty { node: hir::TyImplTraitExistential(..), .. }) => {
+            bug!("impl Trait is desugared to existential type items");
         }
 
         _ => &no_generics,
@@ -1056,6 +1043,12 @@
                     let substs = Substs::identity_for_item(tcx, def_id);
                     tcx.mk_adt(def, substs)
                 }
+                // this is only reachable once we have named existential types
+                ItemExistential(hir::ExistTy { impl_trait_fn: None, .. }) => unimplemented!(),
+                // existential types desugared from impl Trait
+                ItemExistential(hir::ExistTy { impl_trait_fn: Some(owner), .. }) => {
+                    tcx.typeck_tables_of(owner).concrete_existential_types[&def_id]
+                },
                 ItemTrait(..) | ItemTraitAlias(..) |
                 ItemMod(..) |
                 ItemForeignMod(..) |
@@ -1130,12 +1123,6 @@
             icx.to_ty(ty)
         }
 
-        NodeTy(&hir::Ty { node: TyImplTraitExistential(..), .. }) => {
-            let owner = tcx.hir.get_parent_did(node_id);
-            let hir_id = tcx.hir.node_to_hir_id(node_id);
-            tcx.typeck_tables_of(owner).node_id_to_type(hir_id)
-        }
-
         x => {
             bug!("unexpected sort of node in type_of_def_id(): {:?}", x);
         }
@@ -1353,6 +1340,24 @@
                     }, items));
                     generics
                 }
+                ItemExistential(ref exist_ty) => {
+                    let substs = Substs::identity_for_item(tcx, def_id);
+                    let anon_ty = tcx.mk_anon(def_id, substs);
+
+                    // Collect the bounds, i.e. the `A+B+'c` in `impl A+B+'c`.
+                    let bounds = compute_bounds(&icx,
+                                                anon_ty,
+                                                &exist_ty.bounds,
+                                                SizedByDefault::Yes,
+                                                tcx.def_span(def_id));
+
+                    let predicates = bounds.predicates(tcx, anon_ty);
+
+                    return ty::GenericPredicates {
+                        parent: None,
+                        predicates: predicates
+                    };
+                }
 
                 _ => &no_generics,
             }
@@ -1366,31 +1371,6 @@
             }
         }
 
-        NodeTy(&Ty { node: TyImplTraitExistential(ref exist_ty, _), span, .. }) => {
-            let substs = Substs::identity_for_item(tcx, def_id);
-            let anon_ty = tcx.mk_anon(def_id, substs);
-
-            debug!("explicit_predicates_of: anon_ty={:?}", anon_ty);
-
-            // Collect the bounds, i.e. the `A+B+'c` in `impl A+B+'c`.
-            let bounds = compute_bounds(&icx,
-                                        anon_ty,
-                                        &exist_ty.bounds,
-                                        SizedByDefault::Yes,
-                                        span);
-
-            debug!("explicit_predicates_of: bounds={:?}", bounds);
-
-            let predicates = bounds.predicates(tcx, anon_ty);
-
-            debug!("explicit_predicates_of: predicates={:?}", predicates);
-
-            return ty::GenericPredicates {
-                parent: None,
-                predicates: predicates
-            };
-        }
-
         _ => &no_generics,
     };
 
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index e6a66cd..da54eea 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -4581,8 +4581,6 @@
 Erroneous code example:
 
 ```compile_fail,E0690
-#![feature(repr_transparent)]
-
 #[repr(transparent)]
 struct LengthWithUnit<U> { // error: transparent struct needs exactly one
     value: f32,            //        non-zero-sized field, but has 2
@@ -4602,8 +4600,6 @@
 useful:
 
 ```
-#![feature(repr_transparent)]
-
 use std::marker::PhantomData;
 
 #[repr(transparent)]
@@ -4621,7 +4617,7 @@
 Erroneous code example:
 
 ```compile_fail,E0691
-#![feature(repr_transparent, repr_align, attr_literals)]
+#![feature(repr_align, attr_literals)]
 
 #[repr(align(32))]
 struct ForceAlign32;
@@ -4640,8 +4636,6 @@
 Consider removing the over-aligned zero-sized field:
 
 ```
-#![feature(repr_transparent)]
-
 #[repr(transparent)]
 struct Wrapper(f32);
 ```
@@ -4650,7 +4644,7 @@
 if you need to keep the field for some reason:
 
 ```
-#![feature(repr_transparent, repr_align, attr_literals)]
+#![feature(repr_align, attr_literals)]
 
 use std::marker::PhantomData;
 
@@ -4668,7 +4662,7 @@
 "##,
 
 
-E0908: r##"
+E0699: r##"
 A method was called on a raw pointer whose inner type wasn't completely known.
 
 For example, you may have done something like:
@@ -4797,5 +4791,5 @@
     E0640, // infer outlives requirements
     E0641, // cannot cast to/from a pointer with an unknown kind
     E0645, // trait aliases not finished
-    E0907, // type inside generator must be known in this context
+    E0698, // type inside generator must be known in this context
 }
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 5b7d929..ce7249b 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -104,7 +104,7 @@
 use rustc::infer::InferOk;
 use rustc::ty::subst::Substs;
 use rustc::ty::{self, Ty, TyCtxt};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::traits::{ObligationCause, ObligationCauseCode, TraitEngine};
 use session::{CompileIncomplete, config};
 use util::common::time;
diff --git a/src/librustc_typeck/outlives/mod.rs b/src/librustc_typeck/outlives/mod.rs
index b5ba59d..c6c7e8f 100644
--- a/src/librustc_typeck/outlives/mod.rs
+++ b/src/librustc_typeck/outlives/mod.rs
@@ -11,7 +11,7 @@
 use hir::map as hir_map;
 use rustc::hir;
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::ty::subst::UnpackedKind;
 use rustc::ty::{self, CratePredicatesMap, TyCtxt};
 use rustc_data_structures::sync::Lrc;
diff --git a/src/librustc_typeck/variance/mod.rs b/src/librustc_typeck/variance/mod.rs
index fd2b96410..adea978 100644
--- a/src/librustc_typeck/variance/mod.rs
+++ b/src/librustc_typeck/variance/mod.rs
@@ -17,7 +17,7 @@
 use rustc::hir;
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc::ty::{self, CrateVariancesMap, TyCtxt};
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc_data_structures::sync::Lrc;
 
 /// Defines the `TermsContext` basically houses an arena where we can
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index f112f3c..80eb2d1 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -116,6 +116,23 @@
     Some(ret)
 }
 
+pub fn try_inline_glob(cx: &DocContext, def: Def, visited: &mut FxHashSet<DefId>)
+    -> Option<Vec<clean::Item>>
+{
+    if def == Def::Err { return None }
+    let did = def.def_id();
+    if did.is_local() { return None }
+
+    match def {
+        Def::Mod(did) => {
+            let m = build_module(cx, did, visited);
+            Some(m.items)
+        }
+        // glob imports on things like enums aren't inlined even for local exports, so just bail
+        _ => None,
+    }
+}
+
 pub fn load_attrs(cx: &DocContext, did: DefId) -> clean::Attributes {
     cx.tcx.get_attrs(did).clean(cx)
 }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 2e3ea3d..852a447 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -21,12 +21,12 @@
 
 use syntax;
 use rustc_target::spec::abi::Abi;
-use syntax::ast::{self, AttrStyle, Ident};
+use syntax::ast::{self, AttrStyle, NodeId, Ident};
 use syntax::attr;
 use syntax::codemap::{dummy_spanned, Spanned};
 use syntax::feature_gate::UnstableFeatures;
 use syntax::ptr::P;
-use syntax::symbol::keywords;
+use syntax::symbol::keywords::{self, Keyword};
 use syntax::symbol::{Symbol, InternedString};
 use syntax_pos::{self, DUMMY_SP, Pos, FileName};
 
@@ -46,17 +46,20 @@
 use rustc::util::nodemap::{FxHashMap, FxHashSet};
 use rustc_typeck::hir_ty_to_ty;
 use rustc::infer::region_constraints::{RegionConstraintData, Constraint};
+use rustc::lint as lint;
+
 use std::collections::hash_map::Entry;
 use std::fmt;
-
 use std::default::Default;
 use std::{mem, slice, vec};
 use std::iter::{FromIterator, once};
 use rustc_data_structures::sync::Lrc;
 use std::rc::Rc;
+use std::str::FromStr;
 use std::cell::RefCell;
 use std::sync::Arc;
 use std::u32;
+use std::ops::Range;
 
 use core::{self, DocContext};
 use doctree;
@@ -176,7 +179,7 @@
             _ => unreachable!(),
         }
 
-        let ExternalCrate { name, src, primitives, .. } = LOCAL_CRATE.clean(cx);
+        let ExternalCrate { name, src, primitives, keywords, .. } = LOCAL_CRATE.clean(cx);
         {
             let m = match module.inner {
                 ModuleItem(ref mut m) => m,
@@ -194,6 +197,18 @@
                     inner: PrimitiveItem(prim),
                 }
             }));
+            m.items.extend(keywords.into_iter().map(|(def_id, kw, attrs)| {
+                Item {
+                    source: Span::empty(),
+                    name: Some(kw.clone()),
+                    attrs: attrs,
+                    visibility: Some(Public),
+                    stability: get_stability(cx, def_id),
+                    deprecation: get_deprecation(cx, def_id),
+                    def_id,
+                    inner: KeywordItem(kw),
+                }
+            }));
         }
 
         let mut access_levels = cx.access_levels.borrow_mut();
@@ -219,6 +234,7 @@
     pub src: FileName,
     pub attrs: Attributes,
     pub primitives: Vec<(DefId, PrimitiveType, Attributes)>,
+    pub keywords: Vec<(DefId, String, Attributes)>,
 }
 
 impl Clean<ExternalCrate> for CrateNum {
@@ -285,11 +301,53 @@
               .filter_map(as_primitive).collect()
         };
 
+        let as_keyword = |def: Def| {
+            if let Def::Mod(def_id) = def {
+                let attrs = cx.tcx.get_attrs(def_id).clean(cx);
+                let mut keyword = None;
+                for attr in attrs.lists("doc") {
+                    if let Some(v) = attr.value_str() {
+                        if attr.check_name("keyword") {
+                            keyword = Keyword::from_str(&v.as_str()).ok()
+                                                                    .map(|x| x.name().to_string());
+                            if keyword.is_some() {
+                                break
+                            }
+                            // FIXME: should warn on unknown keywords?
+                        }
+                    }
+                }
+                return keyword.map(|p| (def_id, p, attrs));
+            }
+            None
+        };
+        let keywords = if root.is_local() {
+            cx.tcx.hir.krate().module.item_ids.iter().filter_map(|&id| {
+                let item = cx.tcx.hir.expect_item(id.id);
+                match item.node {
+                    hir::ItemMod(_) => {
+                        as_keyword(Def::Mod(cx.tcx.hir.local_def_id(id.id)))
+                    }
+                    hir::ItemUse(ref path, hir::UseKind::Single)
+                    if item.vis == hir::Visibility::Public => {
+                        as_keyword(path.def).map(|(_, prim, attrs)| {
+                            (cx.tcx.hir.local_def_id(id.id), prim, attrs)
+                        })
+                    }
+                    _ => None
+                }
+            }).collect()
+        } else {
+            cx.tcx.item_children(root).iter().map(|item| item.def)
+              .filter_map(as_keyword).collect()
+        };
+
         ExternalCrate {
             name: cx.tcx.crate_name(*self).to_string(),
             src: krate_src,
             attrs: cx.tcx.get_attrs(root).clean(cx),
             primitives,
+            keywords,
         }
     }
 }
@@ -396,6 +454,9 @@
     pub fn is_extern_crate(&self) -> bool {
         self.type_() == ItemType::ExternCrate
     }
+    pub fn is_keyword(&self) -> bool {
+        self.type_() == ItemType::Keyword
+    }
 
     pub fn is_stripped(&self) -> bool {
         match self.inner { StrippedItem(..) => true, _ => false }
@@ -474,6 +535,7 @@
     AssociatedTypeItem(Vec<TyParamBound>, Option<Type>),
     /// An item that has been stripped by a rustdoc pass
     StrippedItem(Box<ItemEnum>),
+    KeywordItem(String),
 }
 
 impl ItemEnum {
@@ -954,12 +1016,20 @@
     (kind, article, format!("{}@{}", kind, path_str))
 }
 
+fn span_of_attrs(attrs: &Attributes) -> syntax_pos::Span {
+    if attrs.doc_strings.is_empty() {
+        return DUMMY_SP;
+    }
+    let start = attrs.doc_strings[0].span();
+    let end = attrs.doc_strings.last().unwrap().span();
+    start.to(end)
+}
+
 fn ambiguity_error(cx: &DocContext, attrs: &Attributes,
                    path_str: &str,
                    article1: &str, kind1: &str, disambig1: &str,
                    article2: &str, kind2: &str, disambig2: &str) {
-    let sp = attrs.doc_strings.first()
-                  .map_or(DUMMY_SP, |a| a.span());
+    let sp = span_of_attrs(attrs);
     cx.sess()
       .struct_span_warn(sp,
                         &format!("`{}` is both {} {} and {} {}",
@@ -1034,7 +1104,7 @@
             // early return and try looking for the trait
             let value = match result.def {
                 Def::Method(_) | Def::AssociatedConst(_) => true,
-                Def::AssociatedTy(_)  => false,
+                Def::AssociatedTy(_) => false,
                 Def::Variant(_) => return handle_variant(cx, result.def),
                 // not a trait item, just return what we found
                 _ => return Ok((result.def, None))
@@ -1174,8 +1244,80 @@
     Type,
 }
 
-fn resolution_failure(cx: &DocContext, path_str: &str) {
-    cx.sess().warn(&format!("[{}] cannot be resolved, ignoring it...", path_str));
+fn resolution_failure(
+    cx: &DocContext,
+    attrs: &Attributes,
+    path_str: &str,
+    dox: &str,
+    link_range: Option<Range<usize>>,
+) {
+    let sp = span_of_attrs(attrs);
+    let msg = format!("`[{}]` cannot be resolved, ignoring it...", path_str);
+
+    let code_dox = sp.to_src(cx);
+
+    let doc_comment_padding = 3;
+    let mut diag = if let Some(link_range) = link_range {
+        // blah blah blah\nblah\nblah [blah] blah blah\nblah blah
+        //                       ^    ~~~~~~
+        //                       |    link_range
+        //                       last_new_line_offset
+
+        let mut diag;
+        if dox.lines().count() == code_dox.lines().count() {
+            let line_offset = dox[..link_range.start].lines().count();
+            // The span starts in the `///`, so we don't have to account for the leading whitespace
+            let code_dox_len = if line_offset <= 1 {
+                doc_comment_padding
+            } else {
+                // The first `///`
+                doc_comment_padding +
+                    // Each subsequent leading whitespace and `///`
+                    code_dox.lines().skip(1).take(line_offset - 1).fold(0, |sum, line| {
+                        sum + doc_comment_padding + line.len() - line.trim().len()
+                    })
+            };
+
+            // Extract the specific span
+            let sp = sp.from_inner_byte_pos(
+                link_range.start + code_dox_len,
+                link_range.end + code_dox_len,
+            );
+
+            diag = cx.tcx.struct_span_lint_node(lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
+                                                NodeId::new(0),
+                                                sp,
+                                                &msg);
+            diag.span_label(sp, "cannot be resolved, ignoring");
+        } else {
+            diag = cx.tcx.struct_span_lint_node(lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
+                                                NodeId::new(0),
+                                                sp,
+                                                &msg);
+
+            let last_new_line_offset = dox[..link_range.start].rfind('\n').map_or(0, |n| n + 1);
+            let line = dox[last_new_line_offset..].lines().next().unwrap_or("");
+
+            // Print the line containing the `link_range` and manually mark it with '^'s
+            diag.note(&format!(
+                "the link appears in this line:\n\n{line}\n\
+                 {indicator: <before$}{indicator:^<found$}",
+                line=line,
+                indicator="",
+                before=link_range.start - last_new_line_offset,
+                found=link_range.len(),
+            ));
+        }
+        diag
+    } else {
+        cx.tcx.struct_span_lint_node(lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
+                                     NodeId::new(0),
+                                     sp,
+                                     &msg)
+    };
+    diag.help("to escape `[` and `]` characters, just add '\\' before them like \
+               `\\[` or `\\]`");
+    diag.emit();
 }
 
 impl Clean<Attributes> for [ast::Attribute] {
@@ -1184,7 +1326,7 @@
 
         if UnstableFeatures::from_environment().is_nightly_build() {
             let dox = attrs.collapsed_doc_value().unwrap_or_else(String::new);
-            for ori_link in markdown_links(&dox) {
+            for (ori_link, link_range) in markdown_links(&dox) {
                 // bail early for real links
                 if ori_link.contains('/') {
                     continue;
@@ -1228,7 +1370,7 @@
                             if let Ok(def) = resolve(cx, path_str, true) {
                                 def
                             } else {
-                                resolution_failure(cx, path_str);
+                                resolution_failure(cx, &attrs, path_str, &dox, link_range);
                                 // this could just be a normal link or a broken link
                                 // we could potentially check if something is
                                 // "intra-doc-link-like" and warn in that case
@@ -1239,7 +1381,7 @@
                             if let Ok(def) = resolve(cx, path_str, false) {
                                 def
                             } else {
-                                resolution_failure(cx, path_str);
+                                resolution_failure(cx, &attrs, path_str, &dox, link_range);
                                 // this could just be a normal link
                                 continue;
                             }
@@ -1284,7 +1426,7 @@
                             } else if let Ok(value_def) = resolve(cx, path_str, true) {
                                 value_def
                             } else {
-                                resolution_failure(cx, path_str);
+                                resolution_failure(cx, &attrs, path_str, &dox, link_range);
                                 // this could just be a normal link
                                 continue;
                             }
@@ -1293,7 +1435,7 @@
                             if let Some(def) = macro_resolve(cx, path_str) {
                                 (def, None)
                             } else {
-                                resolution_failure(cx, path_str);
+                                resolution_failure(cx, &attrs, path_str, &dox, link_range);
                                 continue
                             }
                         }
@@ -2797,7 +2939,14 @@
                 }
             }
             TyBareFn(ref barefn) => BareFunction(box barefn.clean(cx)),
-            TyImplTraitExistential(ref exist_ty, ref _lts) => ImplTrait(exist_ty.bounds.clean(cx)),
+            TyImplTraitExistential(hir_id, _, _) => {
+                match cx.tcx.hir.expect_item(hir_id.id).node {
+                    hir::ItemExistential(ref exist_ty) => {
+                        ImplTrait(exist_ty.bounds.clean(cx))
+                    },
+                    ref other => panic!("impl Trait pointed to {:#?}", other),
+                }
+            },
             TyInfer | TyErr => Infer,
             TyTypeof(..) => panic!("Unimplemented type {:?}", self.node),
         }
@@ -3030,7 +3179,7 @@
         Some(match *self {
             hir::Visibility::Public => Visibility::Public,
             hir::Visibility::Inherited => Visibility::Inherited,
-            hir::Visibility::Crate => Visibility::Crate,
+            hir::Visibility::Crate(_) => Visibility::Crate,
             hir::Visibility::Restricted { ref path, .. } => {
                 let path = path.clean(cx);
                 let did = register_def(cx, path.def);
@@ -3732,6 +3881,13 @@
         });
         let path = self.path.clean(cx);
         let inner = if self.glob {
+            if !denied {
+                let mut visited = FxHashSet();
+                if let Some(items) = inline::try_inline_glob(cx, path.def, &mut visited) {
+                    return items;
+                }
+            }
+
             Import::Glob(resolve_use_source(cx, path))
         } else {
             let name = self.name;
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 458ed10..e858f10 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -17,7 +17,7 @@
 use rustc::middle::privacy::AccessLevels;
 use rustc::ty::{self, TyCtxt, AllArenas};
 use rustc::hir::map as hir_map;
-use rustc::lint;
+use rustc::lint::{self, LintPass};
 use rustc::session::config::ErrorOutputType;
 use rustc::util::nodemap::{FxHashMap, FxHashSet};
 use rustc_resolve as resolve;
@@ -187,7 +187,20 @@
         _ => None
     };
 
-    let warning_lint = lint::builtin::WARNINGS.name_lower();
+    let intra_link_resolution_failure_name = lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE.name;
+    let warnings_lint_name = lint::builtin::WARNINGS.name;
+    let lints = lint::builtin::HardwiredLints.get_lints()
+                    .iter()
+                    .chain(rustc_lint::SoftLints.get_lints())
+                    .filter_map(|lint| {
+                        if lint.name == warnings_lint_name ||
+                           lint.name == intra_link_resolution_failure_name {
+                            None
+                        } else {
+                            Some((lint.name_lower(), lint::Allow))
+                        }
+                    })
+                    .collect::<Vec<_>>();
 
     let host_triple = TargetTriple::from_triple(config::host_triple());
     // plays with error output here!
@@ -195,8 +208,12 @@
         maybe_sysroot,
         search_paths,
         crate_types: vec![config::CrateTypeRlib],
-        lint_opts: if !allow_warnings { vec![(warning_lint, lint::Allow)] } else { vec![] },
-        lint_cap: Some(lint::Allow),
+        lint_opts: if !allow_warnings {
+            lints
+        } else {
+            vec![]
+        },
+        lint_cap: Some(lint::Forbid),
         cg,
         externs,
         target_triple: triple.unwrap_or(host_triple),
@@ -230,7 +247,10 @@
 
         let krate = panictry!(driver::phase_1_parse_input(control, &sess, &input));
 
-        let name = ::rustc_codegen_utils::link::find_crate_name(Some(&sess), &krate.attrs, &input);
+        let name = match crate_name {
+            Some(ref crate_name) => crate_name.clone(),
+            None => ::rustc_codegen_utils::link::find_crate_name(Some(&sess), &krate.attrs, &input),
+        };
 
         let mut crate_loader = CrateLoader::new(&sess, &cstore, &name);
 
@@ -247,10 +267,12 @@
                                                         |_| Ok(()));
         let driver::InnerExpansionResult {
             mut hir_forest,
-            resolver,
+            mut resolver,
             ..
         } = abort_on_err(result, &sess);
 
+        resolver.ignore_extern_prelude_feature = true;
+
         // We need to hold on to the complete resolver, so we clone everything
         // for the analysis passes to use. Suboptimal, but necessary in the
         // current architecture.
diff --git a/src/librustdoc/html/item_type.rs b/src/librustdoc/html/item_type.rs
index 537828d..9b8ada1 100644
--- a/src/librustdoc/html/item_type.rs
+++ b/src/librustdoc/html/item_type.rs
@@ -42,6 +42,7 @@
     AssociatedConst = 18,
     Union           = 19,
     ForeignType     = 20,
+    Keyword         = 21,
 }
 
 
@@ -50,6 +51,7 @@
     Type,
     Value,
     Macro,
+    Keyword,
 }
 
 impl<'a> From<&'a clean::Item> for ItemType {
@@ -83,6 +85,7 @@
             clean::AssociatedConstItem(..) => ItemType::AssociatedConst,
             clean::AssociatedTypeItem(..)  => ItemType::AssociatedType,
             clean::ForeignTypeItem         => ItemType::ForeignType,
+            clean::KeywordItem(..)         => ItemType::Keyword,
             clean::StrippedItem(..)        => unreachable!(),
         }
     }
@@ -131,6 +134,7 @@
             ItemType::Constant        => "constant",
             ItemType::AssociatedConst => "associatedconstant",
             ItemType::ForeignType     => "foreigntype",
+            ItemType::Keyword         => "keyword",
         }
     }
 
@@ -159,6 +163,8 @@
             ItemType::AssociatedConst => NameSpace::Value,
 
             ItemType::Macro => NameSpace::Macro,
+
+            ItemType::Keyword => NameSpace::Keyword,
         }
     }
 }
@@ -172,6 +178,7 @@
 pub const NAMESPACE_TYPE: &'static str = "t";
 pub const NAMESPACE_VALUE: &'static str = "v";
 pub const NAMESPACE_MACRO: &'static str = "m";
+pub const NAMESPACE_KEYWORD: &'static str = "k";
 
 impl NameSpace {
     pub fn to_static_str(&self) -> &'static str {
@@ -179,6 +186,7 @@
             NameSpace::Type => NAMESPACE_TYPE,
             NameSpace::Value => NAMESPACE_VALUE,
             NameSpace::Macro => NAMESPACE_MACRO,
+            NameSpace::Keyword => NAMESPACE_KEYWORD,
         }
     }
 }
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index c09bd4c..7088104 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -32,6 +32,8 @@
 use std::collections::{HashMap, VecDeque};
 use std::default::Default;
 use std::fmt::{self, Write};
+use std::borrow::Cow;
+use std::ops::Range;
 use std::str;
 use syntax::feature_gate::UnstableFeatures;
 use syntax::codemap::Span;
@@ -747,7 +749,7 @@
     s
 }
 
-pub fn markdown_links(md: &str) -> Vec<String> {
+pub fn markdown_links(md: &str) -> Vec<(String, Option<Range<usize>>)> {
     if md.is_empty() {
         return vec![];
     }
@@ -760,8 +762,22 @@
     let shortcut_links = RefCell::new(vec![]);
 
     {
+        let locate = |s: &str| unsafe {
+            let s_start = s.as_ptr();
+            let s_end = s_start.add(s.len());
+            let md_start = md.as_ptr();
+            let md_end = md_start.add(md.len());
+            if md_start <= s_start && s_end <= md_end {
+                let start = s_start.offset_from(md_start) as usize;
+                let end = s_end.offset_from(md_start) as usize;
+                Some(start..end)
+            } else {
+                None
+            }
+        };
+
         let push = |_: &str, s: &str| {
-            shortcut_links.borrow_mut().push(s.to_owned());
+            shortcut_links.borrow_mut().push((s.to_owned(), locate(s)));
             None
         };
         let p = Parser::new_with_broken_link_callback(md, opts,
@@ -772,7 +788,10 @@
         for ev in iter {
             if let Event::Start(Tag::Link(dest, _)) = ev {
                 debug!("found link: {}", dest);
-                links.push(dest.into_owned());
+                links.push(match dest {
+                    Cow::Borrowed(s) => (s.to_owned(), locate(s)),
+                    Cow::Owned(s) => (s, None),
+                });
             }
         }
     }
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 109765b..5c2ec20 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1541,6 +1541,7 @@
     typedefs: HashSet<ItemEntry>,
     statics: HashSet<ItemEntry>,
     constants: HashSet<ItemEntry>,
+    keywords: HashSet<ItemEntry>,
 }
 
 impl AllTypes {
@@ -1556,6 +1557,7 @@
             typedefs: HashSet::with_capacity(100),
             statics: HashSet::with_capacity(100),
             constants: HashSet::with_capacity(100),
+            keywords: HashSet::with_capacity(100),
         }
     }
 
@@ -2063,12 +2065,13 @@
             clean::StaticItem(..) | clean::ForeignStaticItem(..) => write!(fmt, "Static ")?,
             clean::ConstantItem(..) => write!(fmt, "Constant ")?,
             clean::ForeignTypeItem => write!(fmt, "Foreign Type ")?,
+            clean::KeywordItem(..) => write!(fmt, "Keyword ")?,
             _ => {
                 // We don't generate pages for any other type.
                 unreachable!();
             }
         }
-        if !self.item.is_primitive() {
+        if !self.item.is_primitive() && !self.item.is_keyword() {
             let cur = &self.cx.current;
             let amt = if self.item.is_mod() { cur.len() - 1 } else { cur.len() };
             for (i, component) in cur.iter().enumerate().take(amt) {
@@ -2126,6 +2129,7 @@
                 item_static(fmt, self.cx, self.item, i),
             clean::ConstantItem(ref c) => item_constant(fmt, self.cx, self.item, c),
             clean::ForeignTypeItem => item_foreign_type(fmt, self.cx, self.item),
+            clean::KeywordItem(ref k) => item_keyword(fmt, self.cx, self.item, k),
             _ => {
                 // We don't generate pages for any other type.
                 unreachable!();
@@ -2353,29 +2357,7 @@
                 write!(w, "</table>")?;
             }
             curty = myty;
-            let (short, name) = match myty.unwrap() {
-                ItemType::ExternCrate |
-                ItemType::Import          => ("reexports", "Re-exports"),
-                ItemType::Module          => ("modules", "Modules"),
-                ItemType::Struct          => ("structs", "Structs"),
-                ItemType::Union           => ("unions", "Unions"),
-                ItemType::Enum            => ("enums", "Enums"),
-                ItemType::Function        => ("functions", "Functions"),
-                ItemType::Typedef         => ("types", "Type Definitions"),
-                ItemType::Static          => ("statics", "Statics"),
-                ItemType::Constant        => ("constants", "Constants"),
-                ItemType::Trait           => ("traits", "Traits"),
-                ItemType::Impl            => ("impls", "Implementations"),
-                ItemType::TyMethod        => ("tymethods", "Type Methods"),
-                ItemType::Method          => ("methods", "Methods"),
-                ItemType::StructField     => ("fields", "Struct Fields"),
-                ItemType::Variant         => ("variants", "Variants"),
-                ItemType::Macro           => ("macros", "Macros"),
-                ItemType::Primitive       => ("primitives", "Primitive Types"),
-                ItemType::AssociatedType  => ("associated-types", "Associated Types"),
-                ItemType::AssociatedConst => ("associated-consts", "Associated Constants"),
-                ItemType::ForeignType     => ("foreign-types", "Foreign Types"),
-            };
+            let (short, name) = item_ty_to_strs(&myty.unwrap());
             write!(w, "<h2 id='{id}' class='section-header'>\
                        <a href=\"#{id}\">{name}</a></h2>\n<table>",
                    id = derive_id(short.to_owned()), name = name)?;
@@ -3055,6 +3037,7 @@
         } else {
             (0, true)
         };
+        render_attributes(w, meth)?;
         write!(w, "{}{}{}{}fn <a href='{href}' class='fnname'>{name}</a>\
                    {generics}{decl}{where_clause}",
                VisSpace(&meth.visibility),
@@ -4359,6 +4342,33 @@
     Ok(())
 }
 
+fn item_ty_to_strs(ty: &ItemType) -> (&'static str, &'static str) {
+    match *ty {
+        ItemType::ExternCrate |
+        ItemType::Import          => ("reexports", "Re-exports"),
+        ItemType::Module          => ("modules", "Modules"),
+        ItemType::Struct          => ("structs", "Structs"),
+        ItemType::Union           => ("unions", "Unions"),
+        ItemType::Enum            => ("enums", "Enums"),
+        ItemType::Function        => ("functions", "Functions"),
+        ItemType::Typedef         => ("types", "Type Definitions"),
+        ItemType::Static          => ("statics", "Statics"),
+        ItemType::Constant        => ("constants", "Constants"),
+        ItemType::Trait           => ("traits", "Traits"),
+        ItemType::Impl            => ("impls", "Implementations"),
+        ItemType::TyMethod        => ("tymethods", "Type Methods"),
+        ItemType::Method          => ("methods", "Methods"),
+        ItemType::StructField     => ("fields", "Struct Fields"),
+        ItemType::Variant         => ("variants", "Variants"),
+        ItemType::Macro           => ("macros", "Macros"),
+        ItemType::Primitive       => ("primitives", "Primitive Types"),
+        ItemType::AssociatedType  => ("associated-types", "Associated Types"),
+        ItemType::AssociatedConst => ("associated-consts", "Associated Constants"),
+        ItemType::ForeignType     => ("foreign-types", "Foreign Types"),
+        ItemType::Keyword         => ("keywords", "Keywords"),
+    }
+}
+
 fn sidebar_module(fmt: &mut fmt::Formatter, _it: &clean::Item,
                   items: &[clean::Item]) -> fmt::Result {
     let mut sidebar = String::new();
@@ -4378,29 +4388,7 @@
                    ItemType::TyMethod, ItemType::Method, ItemType::StructField, ItemType::Variant,
                    ItemType::AssociatedType, ItemType::AssociatedConst, ItemType::ForeignType] {
         if items.iter().any(|it| !it.is_stripped() && it.type_() == myty) {
-            let (short, name) = match myty {
-                ItemType::ExternCrate |
-                ItemType::Import          => ("reexports", "Re-exports"),
-                ItemType::Module          => ("modules", "Modules"),
-                ItemType::Struct          => ("structs", "Structs"),
-                ItemType::Union           => ("unions", "Unions"),
-                ItemType::Enum            => ("enums", "Enums"),
-                ItemType::Function        => ("functions", "Functions"),
-                ItemType::Typedef         => ("types", "Type Definitions"),
-                ItemType::Static          => ("statics", "Statics"),
-                ItemType::Constant        => ("constants", "Constants"),
-                ItemType::Trait           => ("traits", "Traits"),
-                ItemType::Impl            => ("impls", "Implementations"),
-                ItemType::TyMethod        => ("tymethods", "Type Methods"),
-                ItemType::Method          => ("methods", "Methods"),
-                ItemType::StructField     => ("fields", "Struct Fields"),
-                ItemType::Variant         => ("variants", "Variants"),
-                ItemType::Macro           => ("macros", "Macros"),
-                ItemType::Primitive       => ("primitives", "Primitive Types"),
-                ItemType::AssociatedType  => ("associated-types", "Associated Types"),
-                ItemType::AssociatedConst => ("associated-consts", "Associated Constants"),
-                ItemType::ForeignType     => ("foreign-types", "Foreign Types"),
-            };
+            let (short, name) = item_ty_to_strs(&myty);
             sidebar.push_str(&format!("<li><a href=\"#{id}\">{name}</a></li>",
                                       id = short,
                                       name = name));
@@ -4461,6 +4449,12 @@
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)
 }
 
+fn item_keyword(w: &mut fmt::Formatter, cx: &Context,
+                it: &clean::Item,
+                _p: &str) -> fmt::Result {
+    document(w, cx, it)
+}
+
 const BASIC_KEYWORDS: &'static str = "rust, rustlang, rust-lang";
 
 fn make_item_keywords(it: &clean::Item) -> String {
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index bb9a7e4..bb996e0 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -38,7 +38,8 @@
                      "constant",
                      "associatedconstant",
                      "union",
-                     "foreigntype"];
+                     "foreigntype",
+                     "keyword"];
 
     var search_input = document.getElementsByClassName('search-input')[0];
 
@@ -158,6 +159,7 @@
 
     // used for special search precedence
     var TY_PRIMITIVE = itemTypes.indexOf("primitive");
+    var TY_KEYWORD = itemTypes.indexOf("keyword");
 
     onEach(document.getElementsByClassName('js-only'), function(e) {
         removeClass(e, 'js-only');
@@ -463,6 +465,10 @@
                             var res = buildHrefAndPath(obj);
                             obj.displayPath = pathSplitter(res[0]);
                             obj.fullPath = obj.displayPath + obj.name;
+                            if (obj.ty === TY_KEYWORD) {
+                                // To be sure than it isn't considered as duplicate with items.
+                                obj.fullPath += '|k';
+                            }
                             obj.href = res[1];
                             out.push(obj);
                             if (out.length >= MAX_RESULTS) {
@@ -530,11 +536,13 @@
                     b = bbb.index;
                     if (a !== b) { return a - b; }
 
-                    // special precedence for primitive pages
-                    if ((aaa.item.ty === TY_PRIMITIVE) && (bbb.item.ty !== TY_PRIMITIVE)) {
+                    // special precedence for primitive and keyword pages
+                    if ((aaa.item.ty === TY_PRIMITIVE && bbb.item.ty !== TY_KEYWORD) ||
+                        (aaa.item.ty === TY_KEYWORD && bbb.item.ty !== TY_PRIMITIVE)) {
                         return -1;
                     }
-                    if ((bbb.item.ty === TY_PRIMITIVE) && (aaa.item.ty !== TY_PRIMITIVE)) {
+                    if ((bbb.item.ty === TY_PRIMITIVE && aaa.item.ty !== TY_PRIMITIVE) ||
+                        (bbb.item.ty === TY_KEYWORD && aaa.item.ty !== TY_KEYWORD)) {
                         return 1;
                     }
 
@@ -777,7 +785,7 @@
                     case "fn":
                         return (name == "method" || name == "tymethod");
                     case "type":
-                        return (name == "primitive");
+                        return (name == "primitive" || name == "keyword");
                 }
 
                 // No match
@@ -1206,7 +1214,7 @@
                 displayPath = item.path + '::';
                 href = rootPath + item.path.replace(/::/g, '/') + '/' +
                        name + '/index.html';
-            } else if (type === "primitive") {
+            } else if (type === "primitive" || type === "keyword") {
                 displayPath = "";
                 href = rootPath + item.path.replace(/::/g, '/') +
                        '/' + type + '.' + name + '.html';
@@ -1700,6 +1708,7 @@
         block("fn", "Functions");
         block("type", "Type Definitions");
         block("foreigntype", "Foreign Types");
+        block("keyword", "Keywords");
     }
 
     window.initSidebarItems = initSidebarItems;
@@ -1770,7 +1779,7 @@
         }
     }
 
-    function toggleAllDocs(pageId) {
+    function toggleAllDocs(pageId, fromAutoCollapse) {
         var toggle = document.getElementById("toggle-all-docs");
         if (!toggle) {
             return;
@@ -1782,9 +1791,11 @@
                 e.innerHTML = labelForToggleButton(false);
             });
             toggle.title = "collapse all docs";
-            onEach(document.getElementsByClassName("collapse-toggle"), function(e) {
-                collapseDocs(e, "show");
-            });
+            if (fromAutoCollapse !== true) {
+                onEach(document.getElementsByClassName("collapse-toggle"), function(e) {
+                    collapseDocs(e, "show");
+                });
+            }
         } else {
             updateLocalStorage("rustdoc-collapse", "true");
             addClass(toggle, "will-expand");
@@ -1792,10 +1803,11 @@
                 e.innerHTML = labelForToggleButton(true);
             });
             toggle.title = "expand all docs";
-
-            onEach(document.getElementsByClassName("collapse-toggle"), function(e) {
-                collapseDocs(e, "hide", pageId);
-            });
+            if (fromAutoCollapse !== true) {
+                onEach(document.getElementsByClassName("collapse-toggle"), function(e) {
+                    collapseDocs(e, "hide", pageId);
+                });
+            }
         }
     }
 
@@ -1916,17 +1928,19 @@
         }
     }
 
-    function autoCollapseAllImpls(pageId) {
-        // Automatically minimize all non-inherent impls
-        onEach(document.getElementsByClassName('impl'), function(n) {
-            // inherent impl ids are like 'impl' or impl-<number>'
-            var inherent = (n.id.match(/^impl(?:-\d+)?$/) !== null);
-            if (!inherent) {
-                onEach(n.childNodes, function(m) {
-                    if (hasClass(m, "collapse-toggle")) {
-                        collapseDocs(m, "hide", pageId);
-                    }
-                });
+    function autoCollapse(pageId, collapse) {
+        if (collapse) {
+            toggleAllDocs(pageId, true);
+        }
+        onEach(document.getElementsByClassName("collapse-toggle"), function(e) {
+            // inherent impl ids are like 'impl' or impl-<number>'.
+            // they will never be hidden by default.
+            var n = e.parentNode;
+            if (n.id.match(/^impl(?:-\d+)?$/) === null) {
+                // Automatically minimize all non-inherent impls
+                if (collapse || hasClass(n, 'impl')) {
+                    collapseDocs(e, "hide", pageId);
+                }
             }
         });
     }
@@ -2039,18 +2053,16 @@
         }
     });
 
-    autoCollapseAllImpls(getPageId());
-
-    function createToggleWrapper() {
+    function createToggleWrapper(tog) {
         var span = document.createElement('span');
         span.className = 'toggle-label';
         span.style.display = 'none';
         span.innerHTML = '&nbsp;Expand&nbsp;attributes';
-        toggle.appendChild(span);
+        tog.appendChild(span);
 
         var wrapper = document.createElement('div');
         wrapper.className = 'toggle-wrapper toggle-attributes';
-        wrapper.appendChild(toggle);
+        wrapper.appendChild(tog);
         return wrapper;
     }
 
@@ -2078,13 +2090,11 @@
         });
     }
 
-    onEach(document.getElementById('main').getElementsByTagName('pre'), function(e) {
-        onEach(e.getElementsByClassName('attributes'), function(i_e) {
-            i_e.parentNode.insertBefore(createToggleWrapper(), i_e);
-            if (getCurrentValue("rustdoc-item-attributes") !== "false") {
-                collapseDocs(i_e.previousSibling.childNodes[0], "toggle");
-            }
-        });
+    onEach(document.getElementById('main').getElementsByClassName('attributes'), function(i_e) {
+        i_e.parentNode.insertBefore(createToggleWrapper(toggle.cloneNode(true)), i_e);
+        if (getCurrentValue("rustdoc-item-attributes") !== "false") {
+            collapseDocs(i_e.previousSibling.childNodes[0], "toggle");
+        }
     });
 
     onEach(document.getElementsByClassName('rust-example-rendered'), function(e) {
@@ -2172,9 +2182,7 @@
         hideSidebar();
     };
 
-    if (getCurrentValue("rustdoc-collapse") === "true") {
-        toggleAllDocs(getPageId());
-    }
+    autoCollapse(getPageId(), getCurrentValue("rustdoc-collapse") === "true");
 }());
 
 // Sets the focus on the search bar at the top of the page
diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index 83abf35..d684db1 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -561,7 +561,8 @@
 	content: '\2002\00a7\2002';
 }
 
-.docblock a:not(.srclink):hover, .docblock-short a:not(.srclink):hover, .stability a {
+.docblock a:not(.srclink):not(.test-arrow):hover,
+.docblock-short a:not(.srclink):not(.test-arrow):hover, .stability a {
 	text-decoration: underline;
 }
 
@@ -627,6 +628,11 @@
 	font-style: italic;
 }
 
+tr.result span.keyword::after {
+	content: ' (keyword)';
+	font-style: italic;
+}
+
 body.blur > :not(#help) {
 	filter: blur(8px);
 	-webkit-filter: blur(8px);
@@ -771,7 +777,7 @@
 
 .toggle-wrapper {
 	position: relative;
-	margin-top: 5px;
+	margin-top: 0;
 }
 
 .toggle-wrapper.collapsed {
@@ -854,10 +860,19 @@
 
 .attributes {
 	display: block;
-	margin: 0px 0px 0px 30px !important;
+	margin-top: 0px !important;
+	margin-right: 0px;
+	margin-bottom: 0px !important;
+	margin-left: 30px;
 }
 .toggle-attributes.collapsed {
-	margin-bottom: 5px;
+	margin-bottom: 0;
+}
+.impl-items > .toggle-attributes {
+	margin-left: 20px;
+}
+.impl-items .attributes {
+	font-weight: 500;
 }
 
 :target > code {
diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css
index 765ef0c..7add0e21 100644
--- a/src/librustdoc/html/static/themes/dark.css
+++ b/src/librustdoc/html/static/themes/dark.css
@@ -128,6 +128,7 @@
 .content .highlighted.constant,
 .content .highlighted.static { background-color: #0063cc; }
 .content .highlighted.primitive { background-color: #00708a; }
+.content .highlighted.keyword { background-color: #884719; }
 
 .content span.enum, .content a.enum, .block a.current.enum { color: #82b089; }
 .content span.struct, .content a.struct, .block a.current.struct { color: #2dbfb8; }
@@ -145,6 +146,7 @@
 .content span.method, .content a.method, .block a.current.method,
 .content span.tymethod, .content a.tymethod, .block a.current.tymethod,
 .content .fnname{ color: #2BAB63; }
+.content span.keyword, .content a.keyword, .block a.current.keyword { color: #de5249; }
 
 pre.rust .comment { color: #8d8d8b; }
 pre.rust .doccomment { color: #8ca375; }
@@ -163,7 +165,8 @@
 	color: #ddd;
 }
 
-.docblock a:not(.srclink), .docblock-short a:not(.srclink), .stability a {
+.docblock a:not(.srclink):not(.test-arrow), .docblock-short a:not(.srclink):not(.test-arrow),
+.stability a {
 	color: #D2991D;
 }
 
@@ -208,7 +211,7 @@
 	color: grey;
 }
 
-tr.result span.primitive::after {
+tr.result span.primitive::after, tr.result span.keyword::after {
 	color: #ddd;
 }
 
diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css
index 5971dc4..7d99803 100644
--- a/src/librustdoc/html/static/themes/light.css
+++ b/src/librustdoc/html/static/themes/light.css
@@ -128,6 +128,7 @@
 .content .highlighted.constant,
 .content .highlighted.static { background-color: #c3e0ff; }
 .content .highlighted.primitive { background-color: #9aecff; }
+.content .highlighted.keyword { background-color: #f99650; }
 
 .content span.enum, .content a.enum, .block a.current.enum { color: #508157; }
 .content span.struct, .content a.struct, .block a.current.struct { color: #ad448e; }
@@ -145,6 +146,7 @@
 .content span.method, .content a.method, .block a.current.method,
 .content span.tymethod, .content a.tymethod, .block a.current.tymethod,
 .content .fnname { color: #9a6e31; }
+.content span.keyword, .content a.keyword, .block a.current.keyword { color: #de5249; }
 
 pre.rust .comment { color: #8E908C; }
 pre.rust .doccomment { color: #4D4D4C; }
@@ -163,7 +165,8 @@
 	color: #000;
 }
 
-.docblock a:not(.srclink), .docblock-short a:not(.srclink), .stability a {
+.docblock a:not(.srclink):not(.test-arrow), .docblock-short a:not(.srclink):not(.test-arrow),
+.stability a {
 	color: #3873AD;
 }
 
@@ -202,7 +205,7 @@
 	color: grey;
 }
 
-tr.result span.primitive::after {
+tr.result span.primitive::after, tr.result span.keyword::after {
 	color: black;
 }
 
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 1b713a4..97c84d8 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -23,6 +23,7 @@
 #![feature(test)]
 #![feature(vec_remove_item)]
 #![feature(entry_and_modify)]
+#![feature(ptr_offset_from)]
 
 #![recursion_limit="256"]
 
diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs
index 32f0bca..fe116a2 100644
--- a/src/librustdoc/passes/mod.rs
+++ b/src/librustdoc/passes/mod.rs
@@ -126,6 +126,9 @@
 
             // Associated types are never stripped
             clean::AssociatedTypeItem(..) => {}
+
+            // Keywords are never stripped
+            clean::KeywordItem(..) => {}
         }
 
         let fastreturn = match i.inner {
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 8c2555c..10b1a2e 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -244,10 +244,10 @@
                         def_id,
                         attrs: def.attrs.clone().into(),
                         name: def.ident.name,
-                        whence: def.span,
+                        whence: self.cx.tcx.def_span(def_id),
                         matchers,
-                        stab: self.stability(def.id),
-                        depr: self.deprecation(def.id),
+                        stab: self.cx.tcx.lookup_stability(def_id).cloned(),
+                        depr: self.cx.tcx.lookup_deprecation(def_id),
                         imported_from: Some(imported_from),
                     })
                 }
@@ -365,6 +365,11 @@
                 });
                 true
             }
+            hir_map::NodeStructCtor(_) if !glob => {
+                // struct constructors always show up alongside their struct definitions, we've
+                // already processed that so just discard this
+                true
+            }
             _ => false,
         };
         self.view_item_stack.remove(&def_node_id);
@@ -559,6 +564,9 @@
                     om.impls.push(i);
                 }
             },
+            hir::ItemExistential(_) => {
+                // FIXME(oli-obk): actually generate docs for real existential items
+            }
         }
     }
 
diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs
index 15a8b58..4c773fc 100644
--- a/src/librustdoc/visit_lib.rs
+++ b/src/librustdoc/visit_lib.rs
@@ -68,7 +68,8 @@
         }
 
         for item in self.cx.tcx.item_children(def_id).iter() {
-            if !item.is_import || item.vis == Visibility::Public {
+            if self.cx.tcx.def_key(item.def.def_id()).parent.map_or(false, |d| d == def_id.index) ||
+                item.vis == Visibility::Public {
                 self.visit_item(item.def);
             }
         }
diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs
index 4f9dffc..ae74a71 100644
--- a/src/libstd/alloc.rs
+++ b/src/libstd/alloc.rs
@@ -8,32 +8,99 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! dox
+//! Memory allocation APIs
+//!
+//! In a given program, the standard library has one “global” memory allocator
+//! that is used for example by `Box<T>` and `Vec<T>`.
+//!
+//! Currently the default global allocator is unspecified.
+//! The compiler may link to a version of [jemalloc] on some platforms,
+//! but this is not guaranteed.
+//! Libraries, however, like `cdylib`s and `staticlib`s are guaranteed
+//! to use the [`System`] by default.
+//!
+//! [jemalloc]: https://github.com/jemalloc/jemalloc
+//! [`System`]: struct.System.html
+//!
+//! # The `#[global_allocator]` attribute
+//!
+//! This attribute allows configuring the choice of global allocator.
+//! You can use this to implement a completely custom global allocator
+//! to route all default allocation requests to a custom object.
+//!
+//! ```rust
+//! use std::alloc::{GlobalAlloc, System, Layout};
+//!
+//! struct MyAllocator;
+//!
+//! unsafe impl GlobalAlloc for MyAllocator {
+//!     unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+//!         System.alloc(layout)
+//!     }
+//!
+//!     unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
+//!         System.dealloc(ptr, layout)
+//!     }
+//! }
+//!
+//! #[global_allocator]
+//! static GLOBAL: MyAllocator = MyAllocator;
+//!
+//! fn main() {
+//!     // This `Vec` will allocate memory through `GLOBAL` above
+//!     let mut v = Vec::new();
+//!     v.push(1);
+//! }
+//! ```
+//!
+//! The attribute is used on a `static` item whose type implements the
+//! [`GlobalAlloc`] trait. This type can be provided by an external library:
+//!
+//! [`GlobalAlloc`]: ../../core/alloc/trait.GlobalAlloc.html
+//!
+//! ```rust,ignore (demonstrates crates.io usage)
+//! extern crate jemallocator;
+//!
+//! use jemallacator::Jemalloc;
+//!
+//! #[global_allocator]
+//! static GLOBAL: Jemalloc = Jemalloc;
+//!
+//! fn main() {}
+//! ```
+//!
+//! The `#[global_allocator]` can only be used once in a crate
+//! or its recursive dependencies.
 
-#![unstable(issue = "32838", feature = "allocator_api")]
-
-#[doc(inline)] #[allow(deprecated)] pub use alloc_crate::alloc::Heap;
-#[doc(inline)] pub use alloc_crate::alloc::{Global, Layout, oom};
-#[doc(inline)] pub use alloc_system::System;
-#[doc(inline)] pub use core::alloc::*;
+#![stable(feature = "alloc_module", since = "1.28.0")]
 
 use core::sync::atomic::{AtomicPtr, Ordering};
 use core::{mem, ptr};
+use sys_common::util::dumb_print;
+
+#[stable(feature = "alloc_module", since = "1.28.0")]
+#[doc(inline)]
+pub use alloc_crate::alloc::*;
+
+#[stable(feature = "alloc_system_type", since = "1.28.0")]
+#[doc(inline)]
+pub use alloc_system::System;
 
 static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut());
 
 /// Registers a custom OOM hook, replacing any that was previously registered.
 ///
-/// The OOM hook is invoked when an infallible memory allocation fails.
-/// The default hook prints a message to standard error and aborts the
-/// execution, but this behavior can be customized with the [`set_oom_hook`]
-/// and [`take_oom_hook`] functions.
+/// The OOM hook is invoked when an infallible memory allocation fails, before
+/// the runtime aborts. The default hook prints a message to standard error,
+/// but this behavior can be customized with the [`set_oom_hook`] and
+/// [`take_oom_hook`] functions.
 ///
 /// The hook is provided with a `Layout` struct which contains information
 /// about the allocation that failed.
 ///
 /// The OOM hook is a global resource.
-pub fn set_oom_hook(hook: fn(Layout) -> !) {
+#[unstable(feature = "oom_hook", issue = "51245")]
+pub fn set_oom_hook(hook: fn(Layout)) {
     HOOK.store(hook as *mut (), Ordering::SeqCst);
 }
 
@@ -42,7 +109,8 @@
 /// *See also the function [`set_oom_hook`].*
 ///
 /// If no custom hook is registered, the default hook will be returned.
-pub fn take_oom_hook() -> fn(Layout) -> ! {
+#[unstable(feature = "oom_hook", issue = "51245")]
+pub fn take_oom_hook() -> fn(Layout) {
     let hook = HOOK.swap(ptr::null_mut(), Ordering::SeqCst);
     if hook.is_null() {
         default_oom_hook
@@ -51,28 +119,31 @@
     }
 }
 
-fn default_oom_hook(layout: Layout) -> ! {
-    rtabort!("memory allocation of {} bytes failed", layout.size())
+fn default_oom_hook(layout: Layout) {
+    dumb_print(format_args!("memory allocation of {} bytes failed", layout.size()));
 }
 
 #[cfg(not(test))]
 #[doc(hidden)]
 #[lang = "oom"]
+#[unstable(feature = "alloc_internals", issue = "0")]
 pub extern fn rust_oom(layout: Layout) -> ! {
     let hook = HOOK.load(Ordering::SeqCst);
-    let hook: fn(Layout) -> ! = if hook.is_null() {
+    let hook: fn(Layout) = if hook.is_null() {
         default_oom_hook
     } else {
         unsafe { mem::transmute(hook) }
     };
-    hook(layout)
+    hook(layout);
+    unsafe { ::sys::abort_internal(); }
 }
 
 #[cfg(not(test))]
 #[doc(hidden)]
 #[allow(unused_attributes)]
+#[unstable(feature = "alloc_internals", issue = "0")]
 pub mod __default_lib_allocator {
-    use super::{System, Layout, GlobalAlloc, Opaque};
+    use super::{System, Layout, GlobalAlloc};
     // for symbol names src/librustc/middle/allocator.rs
     // for signatures src/librustc_allocator/lib.rs
 
@@ -83,7 +154,7 @@
     #[rustc_std_internal_symbol]
     pub unsafe extern fn __rdl_alloc(size: usize, align: usize) -> *mut u8 {
         let layout = Layout::from_size_align_unchecked(size, align);
-        System.alloc(layout) as *mut u8
+        System.alloc(layout)
     }
 
     #[no_mangle]
@@ -91,7 +162,7 @@
     pub unsafe extern fn __rdl_dealloc(ptr: *mut u8,
                                        size: usize,
                                        align: usize) {
-        System.dealloc(ptr as *mut Opaque, Layout::from_size_align_unchecked(size, align))
+        System.dealloc(ptr, Layout::from_size_align_unchecked(size, align))
     }
 
     #[no_mangle]
@@ -101,13 +172,13 @@
                                        align: usize,
                                        new_size: usize) -> *mut u8 {
         let old_layout = Layout::from_size_align_unchecked(old_size, align);
-        System.realloc(ptr as *mut Opaque, old_layout, new_size) as *mut u8
+        System.realloc(ptr, old_layout, new_size)
     }
 
     #[no_mangle]
     #[rustc_std_internal_symbol]
     pub unsafe extern fn __rdl_alloc_zeroed(size: usize, align: usize) -> *mut u8 {
         let layout = Layout::from_size_align_unchecked(size, align);
-        System.alloc_zeroed(layout) as *mut u8
+        System.alloc_zeroed(layout)
     }
 }
diff --git a/src/libstd/build.rs b/src/libstd/build.rs
index c34877d..c001e4e 100644
--- a/src/libstd/build.rs
+++ b/src/libstd/build.rs
@@ -74,7 +74,6 @@
         }
         println!("cargo:rustc-link-lib=zircon");
         println!("cargo:rustc-link-lib=fdio");
-        println!("cargo:rustc-link-lib=launchpad"); // for std::process
     } else if target.contains("cloudabi") {
         if cfg!(feature = "backtrace") {
             println!("cargo:rustc-link-lib=unwind");
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index 935ea4b..9c77acb 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -2161,14 +2161,13 @@
 }
 
 impl<'a, K, V: Default> Entry<'a, K, V> {
-    #[unstable(feature = "entry_or_default", issue = "44324")]
+    #[stable(feature = "entry_or_default", since = "1.28.0")]
     /// Ensures a value is in the entry by inserting the default value if empty,
     /// and returns a mutable reference to the value in the entry.
     ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(entry_or_default)]
     /// # fn main() {
     /// use std::collections::HashMap;
     ///
@@ -2184,7 +2183,6 @@
             Vacant(entry) => entry.insert(Default::default()),
         }
     }
-
 }
 
 impl<'a, K, V> OccupiedEntry<'a, K, V> {
@@ -2250,6 +2248,11 @@
 
     /// Gets a mutable reference to the value in the entry.
     ///
+    /// If you need a reference to the `OccupiedEntry` which may outlive the
+    /// destruction of the `Entry` value, see [`into_mut`].
+    ///
+    /// [`into_mut`]: #method.into_mut
+    ///
     /// # Examples
     ///
     /// ```
@@ -2261,10 +2264,14 @@
     ///
     /// assert_eq!(map["poneyland"], 12);
     /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
-    ///      *o.get_mut() += 10;
+    ///     *o.get_mut() += 10;
+    ///     assert_eq!(*o.get(), 22);
+    ///
+    ///     // We can use the same Entry multiple times.
+    ///     *o.get_mut() += 2;
     /// }
     ///
-    /// assert_eq!(map["poneyland"], 22);
+    /// assert_eq!(map["poneyland"], 24);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut(&mut self) -> &mut V {
@@ -2274,6 +2281,10 @@
     /// Converts the OccupiedEntry into a mutable reference to the value in the entry
     /// with a lifetime bound to the map itself.
     ///
+    /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`].
+    ///
+    /// [`get_mut`]: #method.get_mut
+    ///
     /// # Examples
     ///
     /// ```
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs
index eed2deb..55f9f4f 100644
--- a/src/libstd/collections/hash/table.rs
+++ b/src/libstd/collections/hash/table.rs
@@ -8,14 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use alloc::{Global, Alloc, Layout, CollectionAllocErr, oom};
-use cmp;
+use alloc::{Global, Alloc, Layout, LayoutErr, CollectionAllocErr, oom};
 use hash::{BuildHasher, Hash, Hasher};
 use marker;
-use mem::{align_of, size_of, needs_drop};
+use mem::{size_of, needs_drop};
 use mem;
 use ops::{Deref, DerefMut};
 use ptr::{self, Unique, NonNull};
+use hint;
 
 use self::BucketState::*;
 
@@ -651,64 +651,22 @@
     }
 }
 
-
-/// Rounds up to a multiple of a power of two. Returns the closest multiple
-/// of `target_alignment` that is higher or equal to `unrounded`.
-///
-/// # Panics
-///
-/// Panics if `target_alignment` is not a power of two.
-#[inline]
-fn round_up_to_next(unrounded: usize, target_alignment: usize) -> usize {
-    assert!(target_alignment.is_power_of_two());
-    (unrounded + target_alignment - 1) & !(target_alignment - 1)
-}
-
-#[test]
-fn test_rounding() {
-    assert_eq!(round_up_to_next(0, 4), 0);
-    assert_eq!(round_up_to_next(1, 4), 4);
-    assert_eq!(round_up_to_next(2, 4), 4);
-    assert_eq!(round_up_to_next(3, 4), 4);
-    assert_eq!(round_up_to_next(4, 4), 4);
-    assert_eq!(round_up_to_next(5, 4), 8);
-}
-
-// Returns a tuple of (pairs_offset, end_of_pairs_offset),
-// from the start of a mallocated array.
-#[inline]
-fn calculate_offsets(hashes_size: usize,
-                     pairs_size: usize,
-                     pairs_align: usize)
-                     -> (usize, usize, bool) {
-    let pairs_offset = round_up_to_next(hashes_size, pairs_align);
-    let (end_of_pairs, oflo) = pairs_offset.overflowing_add(pairs_size);
-
-    (pairs_offset, end_of_pairs, oflo)
-}
-
-// Returns a tuple of (minimum required malloc alignment,
-// array_size), from the start of a mallocated array.
-fn calculate_allocation(hash_size: usize,
-                        hash_align: usize,
-                        pairs_size: usize,
-                        pairs_align: usize)
-                        -> (usize, usize, bool) {
-    let (_, end_of_pairs, oflo) = calculate_offsets(hash_size, pairs_size, pairs_align);
-
-    let align = cmp::max(hash_align, pairs_align);
-
-    (align, end_of_pairs, oflo)
-}
-
-#[test]
-fn test_offset_calculation() {
-    assert_eq!(calculate_allocation(128, 8, 16, 8), (8, 144, false));
-    assert_eq!(calculate_allocation(3, 1, 2, 1), (1, 5, false));
-    assert_eq!(calculate_allocation(6, 2, 12, 4), (4, 20, false));
-    assert_eq!(calculate_offsets(128, 15, 4), (128, 143, false));
-    assert_eq!(calculate_offsets(3, 2, 4), (4, 6, false));
-    assert_eq!(calculate_offsets(6, 12, 4), (8, 20, false));
+// Returns a Layout which describes the allocation required for a hash table,
+// and the offset of the array of (key, value) pairs in the allocation.
+fn calculate_layout<K, V>(capacity: usize) -> Result<(Layout, usize), LayoutErr> {
+    let hashes = Layout::array::<HashUint>(capacity)?;
+    let pairs = Layout::array::<(K, V)>(capacity)?;
+    hashes.extend(pairs).map(|(layout, _)| {
+        // LLVM seems to have trouble properly const-propagating pairs.align(),
+        // possibly due to the use of NonZeroUsize. This little hack allows it
+        // to generate optimal code.
+        //
+        // See https://github.com/rust-lang/rust/issues/51346 for more details.
+        (
+            layout,
+            hashes.size() + hashes.padding_needed_for(mem::align_of::<(K, V)>()),
+        )
+    })
 }
 
 pub(crate) enum Fallibility {
@@ -735,37 +693,11 @@
             });
         }
 
-        // No need for `checked_mul` before a more restrictive check performed
-        // later in this method.
-        let hashes_size = capacity.wrapping_mul(size_of::<HashUint>());
-        let pairs_size = capacity.wrapping_mul(size_of::<(K, V)>());
-
         // Allocating hashmaps is a little tricky. We need to allocate two
         // arrays, but since we know their sizes and alignments up front,
         // we just allocate a single array, and then have the subarrays
         // point into it.
-        //
-        // This is great in theory, but in practice getting the alignment
-        // right is a little subtle. Therefore, calculating offsets has been
-        // factored out into a different function.
-        let (alignment, size, oflo) = calculate_allocation(hashes_size,
-                                                           align_of::<HashUint>(),
-                                                           pairs_size,
-                                                           align_of::<(K, V)>());
-        if oflo {
-            return Err(CollectionAllocErr::CapacityOverflow);
-        }
-
-        // One check for overflow that covers calculation and rounding of size.
-        let size_of_bucket = size_of::<HashUint>().checked_add(size_of::<(K, V)>())
-            .ok_or(CollectionAllocErr::CapacityOverflow)?;
-        let capacity_mul_size_of_bucket = capacity.checked_mul(size_of_bucket);
-        if capacity_mul_size_of_bucket.is_none() || size < capacity_mul_size_of_bucket.unwrap() {
-            return Err(CollectionAllocErr::CapacityOverflow);
-        }
-
-        let layout = Layout::from_size_align(size, alignment)
-            .map_err(|_| CollectionAllocErr::CapacityOverflow)?;
+        let (layout, _) = calculate_layout::<K, V>(capacity)?;
         let buffer = Global.alloc(layout).map_err(|e| match fallibility {
             Infallible => oom(layout),
             Fallible => e,
@@ -790,18 +722,13 @@
     }
 
     fn raw_bucket_at(&self, index: usize) -> RawBucket<K, V> {
-        let hashes_size = self.capacity() * size_of::<HashUint>();
-        let pairs_size = self.capacity() * size_of::<(K, V)>();
-
-        let (pairs_offset, _, oflo) =
-            calculate_offsets(hashes_size, pairs_size, align_of::<(K, V)>());
-        debug_assert!(!oflo, "capacity overflow");
-
+        let (_, pairs_offset) = calculate_layout::<K, V>(self.capacity())
+            .unwrap_or_else(|_| unsafe { hint::unreachable_unchecked() });
         let buffer = self.hashes.ptr() as *mut u8;
         unsafe {
             RawBucket {
                 hash_start: buffer as *mut HashUint,
-                pair_start: buffer.offset(pairs_offset as isize) as *const (K, V),
+                pair_start: buffer.add(pairs_offset) as *const (K, V),
                 idx: index,
                 _marker: marker::PhantomData,
             }
@@ -1194,18 +1121,10 @@
             }
         }
 
-        let hashes_size = self.capacity() * size_of::<HashUint>();
-        let pairs_size = self.capacity() * size_of::<(K, V)>();
-        let (align, size, oflo) = calculate_allocation(hashes_size,
-                                                       align_of::<HashUint>(),
-                                                       pairs_size,
-                                                       align_of::<(K, V)>());
-
-        debug_assert!(!oflo, "should be impossible");
-
+        let (layout, _) = calculate_layout::<K, V>(self.capacity())
+            .unwrap_or_else(|_| unsafe { hint::unreachable_unchecked() });
         unsafe {
-            Global.dealloc(NonNull::new_unchecked(self.hashes.ptr()).as_opaque(),
-                           Layout::from_size_align(size, align).unwrap());
+            Global.dealloc(NonNull::new_unchecked(self.hashes.ptr()).cast(), layout);
             // Remember how everything was allocated out of one buffer
             // during initialization? We only need one call to free here.
         }
diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs
index d8e79b9..4211341 100644
--- a/src/libstd/collections/mod.rs
+++ b/src/libstd/collections/mod.rs
@@ -438,7 +438,7 @@
 pub use self::hash_set::HashSet;
 
 #[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
-pub use heap::CollectionAllocErr;
+pub use alloc::CollectionAllocErr;
 
 mod hash;
 
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index 817eea5..3160485 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -23,13 +23,13 @@
 // coherence challenge (e.g., specialization, neg impls, etc) we can
 // reconsider what crate these items belong in.
 
+use alloc::{AllocErr, LayoutErr, CannotReallocInPlace};
 use any::TypeId;
 use borrow::Cow;
 use cell;
 use char;
 use core::array;
 use fmt::{self, Debug, Display};
-use heap::{AllocErr, LayoutErr, CannotReallocInPlace};
 use mem::transmute;
 use num;
 use str;
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index 442a087..987687e 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -295,8 +295,6 @@
 /// # Examples
 ///
 /// ```no_run
-/// #![feature(fs_read_write)]
-///
 /// use std::fs;
 /// use std::net::SocketAddr;
 ///
diff --git a/src/libstd/io/lazy.rs b/src/libstd/io/lazy.rs
index 9cef4e3..d357966 100644
--- a/src/libstd/io/lazy.rs
+++ b/src/libstd/io/lazy.rs
@@ -20,6 +20,9 @@
     init: fn() -> Arc<T>,
 }
 
+#[inline]
+const fn done<T>() -> *mut Arc<T> { 1_usize as *mut _ }
+
 unsafe impl<T> Sync for Lazy<T> {}
 
 impl<T: Send + Sync + 'static> Lazy<T> {
@@ -33,17 +36,15 @@
 
     pub fn get(&'static self) -> Option<Arc<T>> {
         unsafe {
-            self.lock.lock();
+            let _guard = self.lock.lock();
             let ptr = self.ptr.get();
-            let ret = if ptr.is_null() {
+            if ptr.is_null() {
                 Some(self.init())
-            } else if ptr as usize == 1 {
+            } else if ptr == done() {
                 None
             } else {
                 Some((*ptr).clone())
-            };
-            self.lock.unlock();
-            return ret
+            }
         }
     }
 
@@ -53,10 +54,10 @@
         // the at exit handler). Otherwise we just return the freshly allocated
         // `Arc`.
         let registered = sys_common::at_exit(move || {
-            self.lock.lock();
-            let ptr = self.ptr.get();
-            self.ptr.set(1 as *mut _);
-            self.lock.unlock();
+            let ptr = {
+                let _guard = self.lock.lock();
+                self.ptr.replace(done())
+            };
             drop(Box::from_raw(ptr))
         });
         let ret = (self.init)();
diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs
new file mode 100644
index 0000000..01bd3ed
--- /dev/null
+++ b/src/libstd/keyword_docs.rs
@@ -0,0 +1,28 @@
+// 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.
+
+#[doc(keyword = "fn")]
+//
+/// The `fn` keyword.
+///
+/// The `fn` keyword is used to declare a function.
+///
+/// Example:
+///
+/// ```rust
+/// fn some_function() {
+///     // code goes in here
+/// }
+/// ```
+///
+/// For more information about functions, take a look at the [Rust Book][book].
+///
+/// [book]: https://doc.rust-lang.org/book/second-edition/ch03-03-how-functions-work.html
+mod fn_keyword { }
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index f7d0685..a6061e9 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -239,6 +239,7 @@
 #![feature(allow_internal_unsafe)]
 #![feature(allow_internal_unstable)]
 #![feature(align_offset)]
+#![feature(arbitrary_self_types)]
 #![feature(array_error_internals)]
 #![feature(ascii_ctype)]
 #![feature(asm)]
@@ -261,8 +262,8 @@
 #![feature(float_from_str_radix)]
 #![feature(fn_traits)]
 #![feature(fnbox)]
+#![feature(futures_api)]
 #![feature(hashmap_internals)]
-#![feature(heap_api)]
 #![feature(int_error_internals)]
 #![feature(integer_atomics)]
 #![feature(into_cow)]
@@ -282,6 +283,7 @@
 #![feature(panic_internals)]
 #![feature(panic_unwind)]
 #![feature(peek)]
+#![feature(pin)]
 #![feature(placement_new_protocol)]
 #![feature(prelude_import)]
 #![feature(ptr_internals)]
@@ -316,7 +318,10 @@
 #![cfg_attr(test, feature(update_panic_count))]
 #![cfg_attr(windows, feature(used))]
 #![feature(doc_alias)]
+#![feature(doc_keyword)]
 #![feature(float_internals)]
+#![feature(panic_info_message)]
+#![cfg_attr(not(stage0), feature(panic_implementation))]
 
 #![default_lib_allocator]
 
@@ -457,6 +462,22 @@
 #[stable(feature = "core_hint", since = "1.27.0")]
 pub use core::hint;
 
+#[unstable(feature = "futures_api",
+           reason = "futures in libcore are unstable",
+           issue = "50547")]
+pub mod task {
+    //! Types and Traits for working with asynchronous tasks.
+    #[doc(inline)]
+    pub use core::task::*;
+    #[doc(inline)]
+    pub use alloc_crate::task::*;
+}
+
+#[unstable(feature = "futures_api",
+           reason = "futures in libcore are unstable",
+           issue = "50547")]
+pub use core::future;
+
 pub mod f32;
 pub mod f64;
 
@@ -478,13 +499,6 @@
 pub mod sync;
 pub mod time;
 
-#[unstable(feature = "allocator_api", issue = "32838")]
-#[rustc_deprecated(since = "1.27.0", reason = "module renamed to `alloc`")]
-/// Use the `alloc` module instead.
-pub mod heap {
-    pub use alloc::*;
-}
-
 // Platform-abstraction modules
 #[macro_use]
 mod sys_common;
@@ -533,3 +547,8 @@
 // the rustdoc documentation for primitive types. Using `include!`
 // because rustdoc only looks for these modules at the crate level.
 include!("primitive_docs.rs");
+
+// Include a number of private modules that exist solely to provide
+// the rustdoc documentation for the existing keywords. Using `include!`
+// because rustdoc only looks for these modules at the crate level.
+include!("keyword_docs.rs");
diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs
index 229034e..4b5a063 100644
--- a/src/libstd/panic.rs
+++ b/src/libstd/panic.rs
@@ -15,11 +15,14 @@
 use any::Any;
 use cell::UnsafeCell;
 use fmt;
+use future::Future;
+use mem::PinMut;
 use ops::{Deref, DerefMut};
 use panicking;
 use ptr::{Unique, NonNull};
 use rc::Rc;
 use sync::{Arc, Mutex, RwLock, atomic};
+use task::{self, Poll};
 use thread::Result;
 
 #[stable(feature = "panic_hooks", since = "1.10.0")]
@@ -315,6 +318,21 @@
     }
 }
 
+#[unstable(feature = "futures_api", issue = "50547")]
+impl<'a, F: Future> Future for AssertUnwindSafe<F> {
+    type Output = F::Output;
+
+    fn poll(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
+        unsafe {
+            let pinned_field = PinMut::new_unchecked(
+                &mut PinMut::get_mut(self.reborrow()).0
+            );
+
+            pinned_field.poll(cx)
+        }
+    }
+}
+
 /// Invokes a closure, capturing the cause of an unwinding panic if one occurs.
 ///
 /// This function will return `Ok` with the closure's result if the closure
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index 4030562..0808efa 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -319,8 +319,8 @@
 
 /// Entry point of panic from the libcore crate.
 #[cfg(not(test))]
+#[cfg(stage0)]
 #[lang = "panic_fmt"]
-#[unwind(allowed)]
 pub extern fn rust_begin_panic(msg: fmt::Arguments,
                                file: &'static str,
                                line: u32,
@@ -328,59 +328,107 @@
     begin_panic_fmt(&msg, &(file, line, col))
 }
 
+/// Entry point of panic from the libcore crate.
+#[cfg(not(test))]
+#[cfg(not(stage0))]
+#[panic_implementation]
+#[unwind(allowed)]
+pub fn rust_begin_panic(info: &PanicInfo) -> ! {
+    continue_panic_fmt(&info)
+}
+
 /// The entry point for panicking with a formatted message.
 ///
 /// This is designed to reduce the amount of code required at the call
 /// site as much as possible (so that `panic!()` has as low an impact
 /// on (e.g.) the inlining of other functions as possible), by moving
 /// the actual formatting into this shared place.
+#[cfg(stage0)]
 #[unstable(feature = "libstd_sys_internals",
            reason = "used by the panic! macro",
            issue = "0")]
 #[inline(never)] #[cold]
 pub fn begin_panic_fmt(msg: &fmt::Arguments,
                        file_line_col: &(&'static str, u32, u32)) -> ! {
-    use fmt::Write;
-
     // We do two allocations here, unfortunately. But (a) they're
     // required with the current scheme, and (b) we don't handle
     // panic + OOM properly anyway (see comment in begin_panic
     // below).
 
     rust_panic_with_hook(&mut PanicPayload::new(msg), Some(msg), file_line_col);
+}
 
-    struct PanicPayload<'a> {
-        inner: &'a fmt::Arguments<'a>,
-        string: Option<String>,
+// NOTE(stage0) move into `continue_panic_fmt` on next stage0 update
+struct PanicPayload<'a> {
+    inner: &'a fmt::Arguments<'a>,
+    string: Option<String>,
+}
+
+impl<'a> PanicPayload<'a> {
+    fn new(inner: &'a fmt::Arguments<'a>) -> PanicPayload<'a> {
+        PanicPayload { inner, string: None }
     }
 
-    impl<'a> PanicPayload<'a> {
-        fn new(inner: &'a fmt::Arguments<'a>) -> PanicPayload<'a> {
-            PanicPayload { inner, string: None }
-        }
+    fn fill(&mut self) -> &mut String {
+        use fmt::Write;
 
-        fn fill(&mut self) -> &mut String {
-            let inner = self.inner;
-            self.string.get_or_insert_with(|| {
-                let mut s = String::new();
-                drop(s.write_fmt(*inner));
-                s
-            })
-        }
+        let inner = self.inner;
+        self.string.get_or_insert_with(|| {
+            let mut s = String::new();
+            drop(s.write_fmt(*inner));
+            s
+        })
+    }
+}
+
+unsafe impl<'a> BoxMeUp for PanicPayload<'a> {
+    fn box_me_up(&mut self) -> *mut (Any + Send) {
+        let contents = mem::replace(self.fill(), String::new());
+        Box::into_raw(Box::new(contents))
     }
 
-    unsafe impl<'a> BoxMeUp for PanicPayload<'a> {
-        fn box_me_up(&mut self) -> *mut (Any + Send) {
-            let contents = mem::replace(self.fill(), String::new());
-            Box::into_raw(Box::new(contents))
-        }
-
-        fn get(&mut self) -> &(Any + Send) {
-            self.fill()
-        }
+    fn get(&mut self) -> &(Any + Send) {
+        self.fill()
     }
 }
 
+/// The entry point for panicking with a formatted message.
+///
+/// This is designed to reduce the amount of code required at the call
+/// site as much as possible (so that `panic!()` has as low an impact
+/// on (e.g.) the inlining of other functions as possible), by moving
+/// the actual formatting into this shared place.
+#[cfg(not(stage0))]
+#[unstable(feature = "libstd_sys_internals",
+           reason = "used by the panic! macro",
+           issue = "0")]
+#[inline(never)] #[cold]
+pub fn begin_panic_fmt(msg: &fmt::Arguments,
+                       file_line_col: &(&'static str, u32, u32)) -> ! {
+    let (file, line, col) = *file_line_col;
+    let info = PanicInfo::internal_constructor(
+        Some(msg),
+        Location::internal_constructor(file, line, col),
+    );
+    continue_panic_fmt(&info)
+}
+
+#[cfg(not(stage0))]
+fn continue_panic_fmt(info: &PanicInfo) -> ! {
+    // We do two allocations here, unfortunately. But (a) they're
+    // required with the current scheme, and (b) we don't handle
+    // panic + OOM properly anyway (see comment in begin_panic
+    // below).
+
+    let loc = info.location().unwrap(); // The current implementation always returns Some
+    let msg = info.message().unwrap(); // The current implementation always returns Some
+    let file_line_col = (loc.file(), loc.line(), loc.column());
+    rust_panic_with_hook(
+        &mut PanicPayload::new(msg),
+        info.message(),
+        &file_line_col);
+}
+
 /// This is the entry point of panicking for panic!() and assert!().
 #[unstable(feature = "libstd_sys_internals",
            reason = "used by the panic! macro",
@@ -431,7 +479,7 @@
 /// abort or unwind.
 fn rust_panic_with_hook(payload: &mut BoxMeUp,
                         message: Option<&fmt::Arguments>,
-                        file_line_col: &(&'static str, u32, u32)) -> ! {
+                        file_line_col: &(&str, u32, u32)) -> ! {
     let (file, line, col) = *file_line_col;
 
     let panics = update_panic_count(1);
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index 13f55e9..3dc1e9c 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -1042,8 +1042,6 @@
 /// # Examples
 ///
 /// ```
-/// #![feature(path_ancestors)]
-///
 /// use std::path::Path;
 ///
 /// let path = Path::new("/foo/bar");
@@ -1056,12 +1054,12 @@
 /// [`ancestors`]: struct.Path.html#method.ancestors
 /// [`Path`]: struct.Path.html
 #[derive(Copy, Clone, Debug)]
-#[unstable(feature = "path_ancestors", issue = "48581")]
+#[stable(feature = "path_ancestors", since = "1.28.0")]
 pub struct Ancestors<'a> {
     next: Option<&'a Path>,
 }
 
-#[unstable(feature = "path_ancestors", issue = "48581")]
+#[stable(feature = "path_ancestors", since = "1.28.0")]
 impl<'a> Iterator for Ancestors<'a> {
     type Item = &'a Path;
 
@@ -1075,7 +1073,7 @@
     }
 }
 
-#[unstable(feature = "path_ancestors", issue = "48581")]
+#[stable(feature = "path_ancestors", since = "1.28.0")]
 impl<'a> FusedIterator for Ancestors<'a> {}
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1890,8 +1888,6 @@
     /// # Examples
     ///
     /// ```
-    /// #![feature(path_ancestors)]
-    ///
     /// use std::path::Path;
     ///
     /// let mut ancestors = Path::new("/foo/bar").ancestors();
@@ -1903,7 +1899,7 @@
     ///
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
     /// [`parent`]: struct.Path.html#method.parent
-    #[unstable(feature = "path_ancestors", issue = "48581")]
+    #[stable(feature = "path_ancestors", since = "1.28.0")]
     pub fn ancestors(&self) -> Ancestors {
         Ancestors {
             next: Some(&self),
diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs
index f3503b0..e5a4106 100644
--- a/src/libstd/sync/mutex.rs
+++ b/src/libstd/sync/mutex.rs
@@ -227,7 +227,7 @@
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn lock(&self) -> LockResult<MutexGuard<T>> {
         unsafe {
-            self.inner.lock();
+            self.inner.raw_lock();
             MutexGuard::new(self)
         }
     }
@@ -454,7 +454,7 @@
     fn drop(&mut self) {
         unsafe {
             self.__lock.poison.done(&self.__poison);
-            self.__lock.inner.unlock();
+            self.__lock.inner.raw_unlock();
         }
     }
 }
diff --git a/src/libstd/sys/redox/args.rs b/src/libstd/sys/redox/args.rs
index 59ae2a7..556ed77 100644
--- a/src/libstd/sys/redox/args.rs
+++ b/src/libstd/sys/redox/args.rs
@@ -73,17 +73,15 @@
             CStr::from_ptr(*argv.offset(i) as *const libc::c_char).to_bytes().to_vec()
         }).collect();
 
-        LOCK.lock();
+        let _guard = LOCK.lock();
         let ptr = get_global_ptr();
         assert!((*ptr).is_none());
         (*ptr) = Some(box args);
-        LOCK.unlock();
     }
 
     pub unsafe fn cleanup() {
-        LOCK.lock();
+        let _guard = LOCK.lock();
         *get_global_ptr() = None;
-        LOCK.unlock();
     }
 
     pub fn args() -> Args {
@@ -96,16 +94,14 @@
 
     fn clone() -> Option<Vec<Vec<u8>>> {
         unsafe {
-            LOCK.lock();
+            let _guard = LOCK.lock();
             let ptr = get_global_ptr();
-            let ret = (*ptr).as_ref().map(|s| (**s).clone());
-            LOCK.unlock();
-            return ret
+            (*ptr).as_ref().map(|s| (**s).clone())
         }
     }
 
-    fn get_global_ptr() -> *mut Option<Box<Vec<Vec<u8>>>> {
-        unsafe { mem::transmute(&GLOBAL_ARGS_PTR) }
+    unsafe fn get_global_ptr() -> *mut Option<Box<Vec<Vec<u8>>>> {
+        mem::transmute(&GLOBAL_ARGS_PTR)
     }
 
 }
diff --git a/src/libstd/sys/redox/os.rs b/src/libstd/sys/redox/os.rs
index 480765b..5822216 100644
--- a/src/libstd/sys/redox/os.rs
+++ b/src/libstd/sys/redox/os.rs
@@ -30,9 +30,6 @@
 use sys::{cvt, fd, syscall};
 use vec;
 
-const TMPBUF_SZ: usize = 128;
-static ENV_LOCK: Mutex = Mutex::new();
-
 extern {
     #[link_name = "__errno_location"]
     fn errno_location() -> *mut i32;
diff --git a/src/libstd/sys/redox/time.rs b/src/libstd/sys/redox/time.rs
index cf79850..5c49111 100644
--- a/src/libstd/sys/redox/time.rs
+++ b/src/libstd/sys/redox/time.rs
@@ -144,7 +144,7 @@
 
     pub fn sub_instant(&self, other: &Instant) -> Duration {
         self.t.sub_timespec(&other.t).unwrap_or_else(|_| {
-            panic!("other was less than the current instant")
+            panic!("specified instant was later than self")
         })
     }
 
diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs
index e1c7ffc..dc1dba6 100644
--- a/src/libstd/sys/unix/args.rs
+++ b/src/libstd/sys/unix/args.rs
@@ -82,17 +82,15 @@
     static LOCK: Mutex = Mutex::new();
 
     pub unsafe fn init(argc: isize, argv: *const *const u8) {
-        LOCK.lock();
+        let _guard = LOCK.lock();
         ARGC = argc;
         ARGV = argv;
-        LOCK.unlock();
     }
 
     pub unsafe fn cleanup() {
-        LOCK.lock();
+        let _guard = LOCK.lock();
         ARGC = 0;
         ARGV = ptr::null();
-        LOCK.unlock();
     }
 
     pub fn args() -> Args {
@@ -104,13 +102,11 @@
 
     fn clone() -> Vec<OsString> {
         unsafe {
-            LOCK.lock();
-            let ret = (0..ARGC).map(|i| {
+            let _guard = LOCK.lock();
+            (0..ARGC).map(|i| {
                 let cstr = CStr::from_ptr(*ARGV.offset(i) as *const libc::c_char);
                 OsStringExt::from_vec(cstr.to_bytes().to_vec())
-            }).collect();
-            LOCK.unlock();
-            return ret
+            }).collect()
         }
     }
 }
diff --git a/src/libstd/sys/unix/ext/mod.rs b/src/libstd/sys/unix/ext/mod.rs
index c221f7c..88e4237 100644
--- a/src/libstd/sys/unix/ext/mod.rs
+++ b/src/libstd/sys/unix/ext/mod.rs
@@ -35,6 +35,7 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 #![doc(cfg(unix))]
+#![allow(missing_docs)]
 
 pub mod io;
 pub mod ffi;
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index c4092dc..7743403 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -890,8 +890,11 @@
                     )
             };
             if let Err(ref copy_err) = copy_result {
-                if let Some(libc::ENOSYS) = copy_err.raw_os_error() {
-                    HAS_COPY_FILE_RANGE.store(false, Ordering::Relaxed);
+                match copy_err.raw_os_error() {
+                    Some(libc::ENOSYS) | Some(libc::EPERM) => {
+                        HAS_COPY_FILE_RANGE.store(false, Ordering::Relaxed);
+                    }
+                    _ => {}
                 }
             }
             copy_result
@@ -902,9 +905,13 @@
             Ok(ret) => written += ret as u64,
             Err(err) => {
                 match err.raw_os_error() {
-                    Some(os_err) if os_err == libc::ENOSYS || os_err == libc::EXDEV => {
-                        // Either kernel is too old or the files are not mounted on the same fs.
-                        // Try again with fallback method
+                    Some(os_err) if os_err == libc::ENOSYS
+                                 || os_err == libc::EXDEV
+                                 || os_err == libc::EPERM => {
+                        // Try fallback io::copy if either:
+                        // - Kernel version is < 4.5 (ENOSYS)
+                        // - Files are mounted on different fs (EXDEV)
+                        // - copy_file_range is disallowed, for example by seccomp (EPERM)
                         assert_eq!(written, 0);
                         let ret = io::copy(&mut reader, &mut writer)?;
                         writer.set_permissions(perm)?;
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index 4c86fdd..82d05f7 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -409,10 +409,9 @@
 /// environment variables of the current process.
 pub fn env() -> Env {
     unsafe {
-        ENV_LOCK.lock();
+        let _guard = ENV_LOCK.lock();
         let mut environ = *environ();
         if environ == ptr::null() {
-            ENV_LOCK.unlock();
             panic!("os::env() failure getting env string from OS: {}",
                    io::Error::last_os_error());
         }
@@ -423,12 +422,10 @@
             }
             environ = environ.offset(1);
         }
-        let ret = Env {
+        return Env {
             iter: result.into_iter(),
             _dont_send_or_sync_me: PhantomData,
-        };
-        ENV_LOCK.unlock();
-        return ret
+        }
     }
 
     fn parse(input: &[u8]) -> Option<(OsString, OsString)> {
@@ -452,15 +449,14 @@
     // always None as well
     let k = CString::new(k.as_bytes())?;
     unsafe {
-        ENV_LOCK.lock();
+        let _guard = ENV_LOCK.lock();
         let s = libc::getenv(k.as_ptr()) as *const libc::c_char;
         let ret = if s.is_null() {
             None
         } else {
             Some(OsStringExt::from_vec(CStr::from_ptr(s).to_bytes().to_vec()))
         };
-        ENV_LOCK.unlock();
-        return Ok(ret)
+        Ok(ret)
     }
 }
 
@@ -469,10 +465,8 @@
     let v = CString::new(v.as_bytes())?;
 
     unsafe {
-        ENV_LOCK.lock();
-        let ret = cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(|_| ());
-        ENV_LOCK.unlock();
-        return ret
+        let _guard = ENV_LOCK.lock();
+        cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(|_| ())
     }
 }
 
@@ -480,10 +474,8 @@
     let nbuf = CString::new(n.as_bytes())?;
 
     unsafe {
-        ENV_LOCK.lock();
-        let ret = cvt(libc::unsetenv(nbuf.as_ptr())).map(|_| ());
-        ENV_LOCK.unlock();
-        return ret
+        let _guard = ENV_LOCK.lock();
+        cvt(libc::unsetenv(nbuf.as_ptr())).map(|_| ())
     }
 }
 
diff --git a/src/libstd/sys/unix/process/process_fuchsia.rs b/src/libstd/sys/unix/process/process_fuchsia.rs
index 06c0540..fa48001 100644
--- a/src/libstd/sys/unix/process/process_fuchsia.rs
+++ b/src/libstd/sys/unix/process/process_fuchsia.rs
@@ -56,68 +56,49 @@
                       -> io::Result<zx_handle_t> {
         use sys::process::zircon::*;
 
-        let job_handle = zx_job_default();
         let envp = match maybe_envp {
             Some(envp) => envp.as_ptr(),
             None => ptr::null(),
         };
 
-        // To make sure launchpad_destroy gets called on the launchpad if this function fails
-        struct LaunchpadDestructor(*mut launchpad_t);
-        impl Drop for LaunchpadDestructor {
-            fn drop(&mut self) { unsafe { launchpad_destroy(self.0); } }
-        }
-
-        // Duplicate the job handle
-        let mut job_copy: zx_handle_t = ZX_HANDLE_INVALID;
-        zx_cvt(zx_handle_duplicate(job_handle, ZX_RIGHT_SAME_RIGHTS, &mut job_copy))?;
-        // Create a launchpad
-        let mut launchpad: *mut launchpad_t = ptr::null_mut();
-        zx_cvt(launchpad_create(job_copy, self.get_argv()[0], &mut launchpad))?;
-        let launchpad_destructor = LaunchpadDestructor(launchpad);
-
-        // Set the process argv
-        zx_cvt(launchpad_set_args(launchpad, self.get_argv().len() as i32 - 1,
-                                  self.get_argv().as_ptr()))?;
-        // Setup the environment vars
-        zx_cvt(launchpad_set_environ(launchpad, envp))?;
-        zx_cvt(launchpad_add_vdso_vmo(launchpad))?;
-        // Load the executable
-        zx_cvt(launchpad_elf_load(launchpad, launchpad_vmo_from_file(self.get_argv()[0])))?;
-        zx_cvt(launchpad_load_vdso(launchpad, ZX_HANDLE_INVALID))?;
-        zx_cvt(launchpad_clone(launchpad, LP_CLONE_FDIO_NAMESPACE | LP_CLONE_FDIO_CWD))?;
+        let transfer_or_clone = |opt_fd, target_fd| if let Some(local_fd) = opt_fd {
+            fdio_spawn_action_t {
+                action: FDIO_SPAWN_ACTION_TRANSFER_FD,
+                local_fd,
+                target_fd,
+                ..Default::default()
+            }
+        } else {
+            fdio_spawn_action_t {
+                action: FDIO_SPAWN_ACTION_CLONE_FD,
+                local_fd: target_fd,
+                target_fd,
+                ..Default::default()
+            }
+        };
 
         // Clone stdin, stdout, and stderr
-        if let Some(fd) = stdio.stdin.fd() {
-            zx_cvt(launchpad_transfer_fd(launchpad, fd, 0))?;
-        } else {
-            zx_cvt(launchpad_clone_fd(launchpad, 0, 0))?;
-        }
-        if let Some(fd) = stdio.stdout.fd() {
-            zx_cvt(launchpad_transfer_fd(launchpad, fd, 1))?;
-        } else {
-            zx_cvt(launchpad_clone_fd(launchpad, 1, 1))?;
-        }
-        if let Some(fd) = stdio.stderr.fd() {
-            zx_cvt(launchpad_transfer_fd(launchpad, fd, 2))?;
-        } else {
-            zx_cvt(launchpad_clone_fd(launchpad, 2, 2))?;
-        }
+        let action1 = transfer_or_clone(stdio.stdin.fd(), 0);
+        let action2 = transfer_or_clone(stdio.stdout.fd(), 1);
+        let action3 = transfer_or_clone(stdio.stderr.fd(), 2);
+        let actions = [action1, action2, action3];
 
-        // We don't want FileDesc::drop to be called on any stdio. It would close their fds. The
-        // fds will be closed once the child process finishes.
+        // We don't want FileDesc::drop to be called on any stdio. fdio_spawn_etc
+        // always consumes transferred file descriptors.
         mem::forget(stdio);
 
         for callback in self.get_closures().iter_mut() {
             callback()?;
         }
 
-        // `launchpad_go` destroys the launchpad, so we must not
-        mem::forget(launchpad_destructor);
-
         let mut process_handle: zx_handle_t = 0;
-        let mut err_msg: *const libc::c_char = ptr::null();
-        zx_cvt(launchpad_go(launchpad, &mut process_handle, &mut err_msg))?;
+        zx_cvt(fdio_spawn_etc(
+            0,
+            FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_LDSVC | FDIO_SPAWN_CLONE_NAMESPACE,
+            self.get_argv()[0], self.get_argv().as_ptr(), envp, 3, actions.as_ptr(),
+            &mut process_handle,
+            ptr::null_mut(),
+        ))?;
         // FIXME: See if we want to do something with that err_msg
 
         Ok(process_handle)
diff --git a/src/libstd/sys/unix/process/zircon.rs b/src/libstd/sys/unix/process/zircon.rs
index 90864e6..a06c73e 100644
--- a/src/libstd/sys/unix/process/zircon.rs
+++ b/src/libstd/sys/unix/process/zircon.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![allow(non_camel_case_types)]
+#![allow(non_camel_case_types, unused)]
 
 use convert::TryInto;
 use io;
@@ -117,75 +117,36 @@
                               avail: *mut size_t) -> zx_status_t;
 }
 
-// From `enum special_handles` in system/ulib/launchpad/launchpad.c
-// HND_LOADER_SVC = 0
-// HND_EXEC_VMO = 1
-// HND_SEGMENTS_VMAR = 2
-const HND_SPECIAL_COUNT: c_int = 3;
-
+#[derive(Default)]
 #[repr(C)]
-pub struct launchpad_t {
-    argc: u32,
-    envc: u32,
-    args: *const c_char,
-    args_len: size_t,
-    env: *const c_char,
-    env_len: size_t,
-
-    handles: *mut zx_handle_t,
-    handles_info: *mut u32,
-    handle_count: size_t,
-    handle_alloc: size_t,
-
-    entry: zx_vaddr_t,
-    base: zx_vaddr_t,
-    vdso_base: zx_vaddr_t,
-
-    stack_size: size_t,
-
-    special_handles: [zx_handle_t; HND_SPECIAL_COUNT as usize],
-    loader_message: bool,
+pub struct fdio_spawn_action_t {
+    pub action: u32,
+    pub reserved0: u32,
+    pub local_fd: i32,
+    pub target_fd: i32,
+    pub reserved1: u64,
 }
 
 extern {
-    pub fn launchpad_create(job: zx_handle_t, name: *const c_char,
-                            lp: *mut *mut launchpad_t) -> zx_status_t;
-
-    pub fn launchpad_go(lp: *mut launchpad_t,
-                        proc_handle: *mut zx_handle_t,
-                        err_msg: *mut *const c_char) -> zx_status_t;
-
-    pub fn launchpad_destroy(lp: *mut launchpad_t);
-
-    pub fn launchpad_set_args(lp: *mut launchpad_t, argc: c_int,
-                               argv: *const *const c_char) -> zx_status_t;
-
-    pub fn launchpad_set_environ(lp: *mut launchpad_t, envp: *const *const c_char) -> zx_status_t;
-
-    pub fn launchpad_clone(lp: *mut launchpad_t, what: u32) -> zx_status_t;
-
-    pub fn launchpad_clone_fd(lp: *mut launchpad_t, fd: c_int, target_fd: c_int) -> zx_status_t;
-
-    pub fn launchpad_transfer_fd(lp: *mut launchpad_t, fd: c_int, target_fd: c_int) -> zx_status_t;
-
-    pub fn launchpad_elf_load(lp: *mut launchpad_t, vmo: zx_handle_t) -> zx_status_t;
-
-    pub fn launchpad_add_vdso_vmo(lp: *mut launchpad_t) -> zx_status_t;
-
-    pub fn launchpad_load_vdso(lp: *mut launchpad_t, vmo: zx_handle_t) -> zx_status_t;
-
-    pub fn launchpad_vmo_from_file(filename: *const c_char) -> zx_handle_t;
+    pub fn fdio_spawn_etc(job: zx_handle_t, flags: u32, path: *const c_char,
+                          argv: *const *const c_char, envp: *const *const c_char,
+                          action_count: u64, actions: *const fdio_spawn_action_t,
+                          process: *mut zx_handle_t, err_msg: *mut c_char) -> zx_status_t;
 }
 
-// Launchpad clone constants
+// fdio_spawn_etc flags
 
-pub const LP_CLONE_FDIO_NAMESPACE: u32 = 0x0001;
-pub const LP_CLONE_FDIO_CWD: u32 = 0x0002;
-// LP_CLONE_FDIO_STDIO = 0x0004
-// LP_CLONE_FDIO_ALL = 0x00FF
-// LP_CLONE_ENVIRON = 0x0100
-// LP_CLONE_DEFAULT_JOB = 0x0200
-// LP_CLONE_ALL = 0xFFFF
+pub const FDIO_SPAWN_CLONE_JOB: u32 = 0x0001;
+pub const FDIO_SPAWN_CLONE_LDSVC: u32 = 0x0002;
+pub const FDIO_SPAWN_CLONE_NAMESPACE: u32 = 0x0004;
+pub const FDIO_SPAWN_CLONE_STDIO: u32 = 0x0008;
+pub const FDIO_SPAWN_CLONE_ENVIRON: u32 = 0x0010;
+pub const FDIO_SPAWN_CLONE_ALL: u32 = 0xFFFF;
+
+// fdio_spawn_etc actions
+
+pub const FDIO_SPAWN_ACTION_CLONE_FD: u32 = 0x0001;
+pub const FDIO_SPAWN_ACTION_TRANSFER_FD: u32 = 0x0002;
 
 // Errors
 
diff --git a/src/libstd/sys/unix/time.rs b/src/libstd/sys/unix/time.rs
index 8312793..89786eb 100644
--- a/src/libstd/sys/unix/time.rs
+++ b/src/libstd/sys/unix/time.rs
@@ -289,7 +289,7 @@
 
         pub fn sub_instant(&self, other: &Instant) -> Duration {
             self.t.sub_timespec(&other.t).unwrap_or_else(|_| {
-                panic!("other was less than the current instant")
+                panic!("specified instant was later than self")
             })
         }
 
diff --git a/src/libstd/sys/windows/ext/mod.rs b/src/libstd/sys/windows/ext/mod.rs
index 4b458d2..1f10609 100644
--- a/src/libstd/sys/windows/ext/mod.rs
+++ b/src/libstd/sys/windows/ext/mod.rs
@@ -18,6 +18,7 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 #![doc(cfg(windows))]
+#![allow(missing_docs)]
 
 pub mod ffi;
 pub mod fs;
diff --git a/src/libstd/sys_common/at_exit_imp.rs b/src/libstd/sys_common/at_exit_imp.rs
index 26da51c..d268d9a 100644
--- a/src/libstd/sys_common/at_exit_imp.rs
+++ b/src/libstd/sys_common/at_exit_imp.rs
@@ -14,6 +14,7 @@
 
 use boxed::FnBox;
 use ptr;
+use mem;
 use sys_common::mutex::Mutex;
 
 type Queue = Vec<Box<FnBox()>>;
@@ -25,6 +26,8 @@
 static LOCK: Mutex = Mutex::new();
 static mut QUEUE: *mut Queue = ptr::null_mut();
 
+const DONE: *mut Queue = 1_usize as *mut _;
+
 // The maximum number of times the cleanup routines will be run. While running
 // the at_exit closures new ones may be registered, and this count is the number
 // of times the new closures will be allowed to register successfully. After
@@ -35,7 +38,7 @@
     if QUEUE.is_null() {
         let state: Box<Queue> = box Vec::new();
         QUEUE = Box::into_raw(state);
-    } else if QUEUE as usize == 1 {
+    } else if QUEUE == DONE {
         // can't re-init after a cleanup
         return false
     }
@@ -44,18 +47,18 @@
 }
 
 pub fn cleanup() {
-    for i in 0..ITERS {
+    for i in 1..=ITERS {
         unsafe {
-            LOCK.lock();
-            let queue = QUEUE;
-            QUEUE = if i == ITERS - 1 {1} else {0} as *mut _;
-            LOCK.unlock();
+            let queue = {
+                let _guard = LOCK.lock();
+                mem::replace(&mut QUEUE, if i == ITERS { DONE } else { ptr::null_mut() })
+            };
 
             // make sure we're not recursively cleaning up
-            assert!(queue as usize != 1);
+            assert!(queue != DONE);
 
             // If we never called init, not need to cleanup!
-            if queue as usize != 0 {
+            if !queue.is_null() {
                 let queue: Box<Queue> = Box::from_raw(queue);
                 for to_run in *queue {
                     to_run();
@@ -66,15 +69,13 @@
 }
 
 pub fn push(f: Box<FnBox()>) -> bool {
-    let mut ret = true;
     unsafe {
-        LOCK.lock();
+        let _guard = LOCK.lock();
         if init() {
             (*QUEUE).push(f);
+            true
         } else {
-            ret = false;
+            false
         }
-        LOCK.unlock();
     }
-    ret
 }
diff --git a/src/libstd/sys_common/mutex.rs b/src/libstd/sys_common/mutex.rs
index d1a7387..608355b 100644
--- a/src/libstd/sys_common/mutex.rs
+++ b/src/libstd/sys_common/mutex.rs
@@ -37,7 +37,15 @@
     /// Behavior is undefined if the mutex has been moved between this and any
     /// previous function call.
     #[inline]
-    pub unsafe fn lock(&self) { self.0.lock() }
+    pub unsafe fn raw_lock(&self) { self.0.lock() }
+
+    /// Calls raw_lock() and then returns an RAII guard to guarantee the mutex
+    /// will be unlocked.
+    #[inline]
+    pub unsafe fn lock(&self) -> MutexGuard {
+        self.raw_lock();
+        MutexGuard(&self.0)
+    }
 
     /// Attempts to lock the mutex without blocking, returning whether it was
     /// successfully acquired or not.
@@ -51,8 +59,11 @@
     ///
     /// Behavior is undefined if the current thread does not actually hold the
     /// mutex.
+    ///
+    /// Consider switching from the pair of raw_lock() and raw_unlock() to
+    /// lock() whenever possible.
     #[inline]
-    pub unsafe fn unlock(&self) { self.0.unlock() }
+    pub unsafe fn raw_unlock(&self) { self.0.unlock() }
 
     /// Deallocates all resources associated with this mutex.
     ///
@@ -64,3 +75,14 @@
 
 // not meant to be exported to the outside world, just the containing module
 pub fn raw(mutex: &Mutex) -> &imp::Mutex { &mutex.0 }
+
+#[must_use]
+/// A simple RAII utility for the above Mutex without the poisoning semantics.
+pub struct MutexGuard<'a>(&'a imp::Mutex);
+
+impl<'a> Drop for MutexGuard<'a> {
+    #[inline]
+    fn drop(&mut self) {
+        unsafe { self.0.unlock(); }
+    }
+}
diff --git a/src/libstd/sys_common/thread_local.rs b/src/libstd/sys_common/thread_local.rs
index d0d6224..75f6b9a 100644
--- a/src/libstd/sys_common/thread_local.rs
+++ b/src/libstd/sys_common/thread_local.rs
@@ -162,13 +162,12 @@
         // we just simplify the whole branch.
         if imp::requires_synchronized_create() {
             static INIT_LOCK: Mutex = Mutex::new();
-            INIT_LOCK.lock();
+            let _guard = INIT_LOCK.lock();
             let mut key = self.key.load(Ordering::SeqCst);
             if key == 0 {
                 key = imp::create(self.dtor) as usize;
                 self.key.store(key, Ordering::SeqCst);
             }
-            INIT_LOCK.unlock();
             rtassert!(key != 0);
             return key
         }
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 1b976b7..1dacf99 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -935,20 +935,17 @@
         static mut COUNTER: u64 = 0;
 
         unsafe {
-            GUARD.lock();
+            let _guard = GUARD.lock();
 
             // If we somehow use up all our bits, panic so that we're not
             // covering up subtle bugs of IDs being reused.
             if COUNTER == ::u64::MAX {
-                GUARD.unlock();
                 panic!("failed to generate unique thread ID: bitspace exhausted");
             }
 
             let id = COUNTER;
             COUNTER += 1;
 
-            GUARD.unlock();
-
             ThreadId(id)
         }
     }
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index df7d480..76fa463 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1860,7 +1860,10 @@
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum UseTreeKind {
     /// `use prefix` or `use prefix as rename`
-    Simple(Option<Ident>),
+    ///
+    /// The extra `NodeId`s are for HIR lowering, when additional statements are created for each
+    /// namespace.
+    Simple(Option<Ident>, NodeId, NodeId),
     /// `use prefix::{...}`
     Nested(Vec<(UseTree, NodeId)>),
     /// `use prefix::*`
@@ -1879,8 +1882,8 @@
 impl UseTree {
     pub fn ident(&self) -> Ident {
         match self.kind {
-            UseTreeKind::Simple(Some(rename)) => rename,
-            UseTreeKind::Simple(None) =>
+            UseTreeKind::Simple(Some(rename), ..) => rename,
+            UseTreeKind::Simple(None, ..) =>
                 self.prefix.segments.last().expect("empty prefix in a simple import").ident,
             _ => panic!("`UseTree::ident` can only be used on a simple import"),
         }
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index 076b6d1..2389ed7 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -17,7 +17,7 @@
 use ast;
 use ast::{AttrId, Attribute, Name, Ident, Path, PathSegment};
 use ast::{MetaItem, MetaItemKind, NestedMetaItem, NestedMetaItemKind};
-use ast::{Lit, LitKind, Expr, ExprKind, Item, Local, Stmt, StmtKind};
+use ast::{Lit, LitKind, Expr, ExprKind, Item, Local, Stmt, StmtKind, GenericParam};
 use codemap::{BytePos, Spanned, respan, dummy_spanned};
 use syntax_pos::Span;
 use errors::{Applicability, Handler};
@@ -1444,6 +1444,22 @@
     }
 }
 
+impl HasAttrs for GenericParam {
+    fn attrs(&self) -> &[ast::Attribute] {
+        match self {
+            GenericParam::Lifetime(lifetime) => lifetime.attrs(),
+            GenericParam::Type(ty) => ty.attrs(),
+        }
+    }
+
+    fn map_attrs<F: FnOnce(Vec<Attribute>) -> Vec<Attribute>>(self, f: F) -> Self {
+        match self {
+            GenericParam::Lifetime(lifetime) => GenericParam::Lifetime(lifetime.map_attrs(f)),
+            GenericParam::Type(ty) => GenericParam::Type(ty.map_attrs(f)),
+        }
+    }
+}
+
 macro_rules! derive_has_attrs {
     ($($ty:path),*) => { $(
         impl HasAttrs for $ty {
@@ -1463,5 +1479,5 @@
 
 derive_has_attrs! {
     Item, Expr, Local, ast::ForeignItem, ast::StructField, ast::ImplItem, ast::TraitItem, ast::Arm,
-    ast::Field, ast::FieldPat, ast::Variant_
+    ast::Field, ast::FieldPat, ast::Variant_, ast::LifetimeDef, ast::TyParam
 }
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index 3691168..3364378 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -278,6 +278,22 @@
             pattern
         })
     }
+
+    // deny #[cfg] on generic parameters until we decide what to do with it.
+    // see issue #51279.
+    pub fn disallow_cfg_on_generic_param(&mut self, param: &ast::GenericParam) {
+        for attr in param.attrs() {
+            let offending_attr = if attr.check_name("cfg") {
+                "cfg"
+            } else if attr.check_name("cfg_attr") {
+                "cfg_attr"
+            } else {
+                continue;
+            };
+            let msg = format!("#[{}] cannot be applied on a generic parameter", offending_attr);
+            self.sess.span_diagnostic.span_err(attr.span, &msg);
+        }
+    }
 }
 
 impl<'a> fold::Folder for StripUnconfigured<'a> {
diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs
index 5f94043..ab8317b 100644
--- a/src/libsyntax/diagnostic_list.rs
+++ b/src/libsyntax/diagnostic_list.rs
@@ -93,6 +93,68 @@
 https://doc.rust-lang.org/reference.html#conditional-compilation
 "##,
 
+E0538: r##"
+Attribute contains same meta item more than once.
+
+Erroneous code example:
+
+```compile_fail,E0538
+#[deprecated(
+    since="1.0.0",
+    note="First deprecation note.",
+    note="Second deprecation note." // error: multiple same meta item
+)]
+fn deprecated_function() {}
+```
+
+Meta items are the key-value pairs inside of an attribute. Each key may only be
+used once in each attribute.
+
+To fix the problem, remove all but one of the meta items with the same key.
+
+Example:
+
+```
+#[deprecated(
+    since="1.0.0",
+    note="First deprecation note."
+)]
+fn deprecated_function() {}
+```
+"##,
+
+E0541: r##"
+An unknown meta item was used.
+
+Erroneous code example:
+
+```compile_fail,E0541
+#[deprecated(
+    since="1.0.0",
+    // error: unknown meta item
+    reason="Example invalid meta item. Should be 'note'")
+]
+fn deprecated_function() {}
+```
+
+Meta items are the key-value pairs inside of an attribute. The keys provided
+must be one of the valid keys for the specified attribute.
+
+To fix the problem, either remove the unknown meta item, or rename it if you
+provided the wrong name.
+
+In the erroneous code example above, the wrong name was provided, so changing
+to a correct one it will fix the error. Example:
+
+```
+#[deprecated(
+    since="1.0.0",
+    note="This is a valid meta item for the deprecated attribute."
+)]
+fn deprecated_function() {}
+```
+"##,
+
 E0552: r##"
 A unrecognized representation attribute was used.
 
@@ -315,10 +377,8 @@
 }
 
 register_diagnostics! {
-    E0538, // multiple [same] items
     E0539, // incorrect meta item
     E0540, // multiple rustc_deprecated attributes
-    E0541, // unknown meta item
     E0542, // missing 'since'
     E0543, // missing 'reason'
     E0544, // multiple stability levels
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 6664c0a..4a6f06d 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -1175,7 +1175,7 @@
         self.item_use(sp, vis, P(ast::UseTree {
             span: sp,
             prefix: path,
-            kind: ast::UseTreeKind::Simple(rename),
+            kind: ast::UseTreeKind::Simple(rename, ast::DUMMY_NODE_ID, ast::DUMMY_NODE_ID),
         }))
     }
 
@@ -1185,7 +1185,7 @@
             (ast::UseTree {
                 span: sp,
                 prefix: self.path(sp, vec![*id]),
-                kind: ast::UseTreeKind::Simple(None),
+                kind: ast::UseTreeKind::Simple(None, ast::DUMMY_NODE_ID, ast::DUMMY_NODE_ID),
             }, ast::DUMMY_NODE_ID)
         }).collect();
 
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 83e7dd8..2903078 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -1412,6 +1412,11 @@
         }
     }
 
+    fn fold_generic_param(&mut self, param: ast::GenericParam) -> ast::GenericParam {
+        self.cfg.disallow_cfg_on_generic_param(&param);
+        noop_fold_generic_param(param, self)
+    }
+
     fn fold_attribute(&mut self, at: ast::Attribute) -> Option<ast::Attribute> {
         // turn `#[doc(include="filename")]` attributes into `#[doc(include(file="filename",
         // contents="file contents")]` attributes
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index b53d94db2..fe458fa 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -827,6 +827,14 @@
             Token::Interpolated(ref nt) => may_be_ident(&nt.0),
             _ => false,
         },
+        "lifetime" => match *token {
+            Token::Lifetime(_) => true,
+            Token::Interpolated(ref nt) => match nt.0 {
+                token::NtLifetime(_) | token::NtTT(_) => true,
+                _ => false,
+            },
+            _ => false,
+        },
         _ => match *token {
             token::CloseDelim(_) => false,
             _ => true,
diff --git a/src/libsyntax/ext/tt/quoted.rs b/src/libsyntax/ext/tt/quoted.rs
index 77c6afa..01b9719 100644
--- a/src/libsyntax/ext/tt/quoted.rs
+++ b/src/libsyntax/ext/tt/quoted.rs
@@ -386,25 +386,71 @@
 {
     // We basically look at two token trees here, denoted as #1 and #2 below
     let span = match parse_kleene_op(input, span) {
-        // #1 is any KleeneOp (`?`)
-        Ok(Ok(op)) if op == KleeneOp::ZeroOrOne => {
-            if !features.macro_at_most_once_rep
-                && !attr::contains_name(attrs, "allow_internal_unstable")
-            {
-                let explain = feature_gate::EXPLAIN_MACRO_AT_MOST_ONCE_REP;
-                emit_feature_err(
-                    sess,
-                    "macro_at_most_once_rep",
-                    span,
-                    GateIssue::Language,
-                    explain,
-                );
-            }
-            return (None, op);
-        }
+        // #1 is a `+` or `*` KleeneOp
+        //
+        // `?` is ambiguous: it could be a separator or a Kleene::ZeroOrOne, so we need to look
+        // ahead one more token to be sure.
+        Ok(Ok(op)) if op != KleeneOp::ZeroOrOne => return (None, op),
 
-        // #1 is any KleeneOp (`+`, `*`)
-        Ok(Ok(op)) => return (None, op),
+        // #1 is `?` token, but it could be a Kleene::ZeroOrOne without a separator or it could
+        // be a `?` separator followed by any Kleene operator. We need to look ahead 1 token to
+        // find out which.
+        Ok(Ok(op)) => {
+            assert_eq!(op, KleeneOp::ZeroOrOne);
+
+            // Lookahead at #2. If it is a KleenOp, then #1 is a separator.
+            let is_1_sep = if let Some(&tokenstream::TokenTree::Token(_, ref tok2)) = input.peek() {
+                kleene_op(tok2).is_some()
+            } else {
+                false
+            };
+
+            if is_1_sep {
+                // #1 is a separator and #2 should be a KleepeOp::*
+                // (N.B. We need to advance the input iterator.)
+                match parse_kleene_op(input, span) {
+                    // #2 is a KleeneOp (this is the only valid option) :)
+                    Ok(Ok(op)) if op == KleeneOp::ZeroOrOne => {
+                        if !features.macro_at_most_once_rep
+                            && !attr::contains_name(attrs, "allow_internal_unstable")
+                        {
+                            let explain = feature_gate::EXPLAIN_MACRO_AT_MOST_ONCE_REP;
+                            emit_feature_err(
+                                sess,
+                                "macro_at_most_once_rep",
+                                span,
+                                GateIssue::Language,
+                                explain,
+                            );
+                        }
+                        return (Some(token::Question), op);
+                    }
+                    Ok(Ok(op)) => return (Some(token::Question), op),
+
+                    // #2 is a random token (this is an error) :(
+                    Ok(Err((_, span))) => span,
+
+                    // #2 is not even a token at all :(
+                    Err(span) => span,
+                }
+            } else {
+                if !features.macro_at_most_once_rep
+                    && !attr::contains_name(attrs, "allow_internal_unstable")
+                {
+                    let explain = feature_gate::EXPLAIN_MACRO_AT_MOST_ONCE_REP;
+                    emit_feature_err(
+                        sess,
+                        "macro_at_most_once_rep",
+                        span,
+                        GateIssue::Language,
+                        explain,
+                    );
+                }
+
+                // #2 is a random tree and #1 is KleeneOp::ZeroOrOne
+                return (None, op);
+            }
+        }
 
         // #1 is a separator followed by #2, a KleeneOp
         Ok(Err((tok, span))) => match parse_kleene_op(input, span) {
@@ -421,11 +467,8 @@
                         GateIssue::Language,
                         explain,
                     );
-                } else {
-                    sess.span_diagnostic
-                        .span_err(span, "`?` macro repetition does not allow a separator");
                 }
-                return (None, op);
+                return (Some(tok), op);
             }
             Ok(Ok(op)) => return (Some(tok), op),
 
@@ -440,7 +483,9 @@
         Err(span) => span,
     };
 
-    if !features.macro_at_most_once_rep && !attr::contains_name(attrs, "allow_internal_unstable") {
+    if !features.macro_at_most_once_rep
+        && !attr::contains_name(attrs, "allow_internal_unstable")
+    {
         sess.span_diagnostic
             .span_err(span, "expected one of: `*`, `+`, or `?`");
     } else {
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 9b84713..a2ea6a2 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -357,8 +357,6 @@
     // Trait aliases
     (active, trait_alias, "1.24.0", Some(41517), None),
 
-    // global allocators and their internals
-    (active, global_allocator, "1.20.0", Some(27389), None),
     // rustc internal
     (active, allocator_internals, "1.20.0", None, None),
 
@@ -398,15 +396,9 @@
     // `foo.rs` as an alternative to `foo/mod.rs`
     (active, non_modrs_mods, "1.24.0", Some(44660), Some(Edition::Edition2018)),
 
-    // Termination trait in tests (RFC 1937)
-    (active, termination_trait_test, "1.24.0", Some(48854), Some(Edition::Edition2018)),
-
     // `extern` in paths
     (active, extern_in_paths, "1.23.0", Some(44660), None),
 
-    // Allows `#[repr(transparent)]` attribute on newtype structs
-    (active, repr_transparent, "1.25.0", Some(43036), None),
-
     // Use `?` as the Kleene "at most one" operator
     (active, macro_at_most_once_rep, "1.25.0", Some(48075), None),
 
@@ -475,6 +467,13 @@
 
     // 'a: { break 'a; }
     (active, label_break_value, "1.28.0", Some(48594), None),
+
+
+    // #[panic_implementation]
+    (active, panic_implementation, "1.28.0", Some(44489), None),
+
+    // #[doc(keyword = "...")]
+    (active, doc_keyword, "1.28.0", Some(51315), None),
 );
 
 declare_features! (
@@ -598,7 +597,7 @@
     // allow `'_` placeholder lifetimes
     (accepted, underscore_lifetimes, "1.26.0", Some(44524), None),
     // Allows attributes on lifetime/type formal parameters in generics (RFC 1327)
-    (accepted, generic_param_attrs, "1.26.0", Some(48848), None),
+    (accepted, generic_param_attrs, "1.27.0", Some(48848), None),
     // Allows cfg(target_feature = "...").
     (accepted, cfg_target_feature, "1.27.0", Some(29717), None),
     // Allows #[target_feature(...)]
@@ -609,6 +608,12 @@
     (accepted, fn_must_use, "1.27.0", Some(43302), None),
     // Allows use of the :lifetime macro fragment specifier
     (accepted, macro_lifetime_matcher, "1.27.0", Some(34303), None),
+    // Termination trait in tests (RFC 1937)
+    (accepted, termination_trait_test, "1.27.0", Some(48854), None),
+    // The #[global_allocator] attribute
+    (accepted, global_allocator, "1.28.0", Some(27389), None),
+    // Allows `#[repr(transparent)]` attribute on newtype structs
+    (accepted, repr_transparent, "1.28.0", Some(43036), None),
 );
 
 // If you change this, please modify src/doc/unstable-book as well. You must
@@ -770,11 +775,7 @@
                                              "the `#[rustc_const_unstable]` attribute \
                                               is an internal feature",
                                              cfg_fn!(rustc_const_unstable))),
-    ("global_allocator", Normal, Gated(Stability::Unstable,
-                                       "global_allocator",
-                                       "the `#[global_allocator]` attribute is \
-                                        an experimental feature",
-                                       cfg_fn!(global_allocator))),
+    ("global_allocator", Normal, Ungated),
     ("default_lib_allocator", Whitelisted, Gated(Stability::Unstable,
                                             "allocator_internals",
                                             "the `#[default_lib_allocator]` \
@@ -1069,6 +1070,12 @@
                                  "attribute is currently unstable",
                                  cfg_fn!(wasm_custom_section))),
 
+    // RFC 2070
+    ("panic_implementation", Normal, Gated(Stability::Unstable,
+                           "panic_implementation",
+                           "#[panic_implementation] is an unstable feature",
+                           cfg_fn!(panic_implementation))),
+
     // Crate level attributes
     ("crate_name", CrateLevel, Ungated),
     ("crate_type", CrateLevel, Ungated),
@@ -1497,6 +1504,10 @@
                     gate_feature_post!(&self, doc_alias, attr.span,
                         "#[doc(alias = \"...\")] is experimental"
                     );
+                } else if content.iter().any(|c| c.check_name("keyword")) {
+                    gate_feature_post!(&self, doc_keyword, attr.span,
+                        "#[doc(keyword = \"...\")] is experimental"
+                    );
                 }
             }
         }
@@ -1534,7 +1545,7 @@
     }
 
     fn visit_use_tree(&mut self, use_tree: &'a ast::UseTree, id: NodeId, _nested: bool) {
-        if let ast::UseTreeKind::Simple(Some(ident)) = use_tree.kind {
+        if let ast::UseTreeKind::Simple(Some(ident), ..) = use_tree.kind {
             if ident.name == "_" {
                 gate_feature_post!(&self, underscore_imports, use_tree.span,
                                    "renaming imports with `_` is unstable");
@@ -1583,11 +1594,6 @@
                             gate_feature_post!(&self, repr_simd, attr.span,
                                                "SIMD types are experimental and possibly buggy");
                         }
-                        if item.check_name("transparent") {
-                            gate_feature_post!(&self, repr_transparent, attr.span,
-                                               "the `#[repr(transparent)]` attribute \
-                                               is experimental");
-                        }
                         if let Some((name, _)) = item.name_value_literal() {
                             if name == "packed" {
                                 gate_feature_post!(&self, repr_packed, attr.span,
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 2f209b3..8544ef3 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -168,6 +168,10 @@
         noop_fold_path(p, self)
     }
 
+    fn fold_qpath(&mut self, qs: Option<QSelf>, p: Path) -> (Option<QSelf>, Path) {
+        noop_fold_qpath(qs, p, self)
+    }
+
     fn fold_path_parameters(&mut self, p: PathParameters) -> PathParameters {
         noop_fold_path_parameters(p, self)
     }
@@ -311,8 +315,9 @@
         span: fld.new_span(use_tree.span),
         prefix: fld.fold_path(use_tree.prefix),
         kind: match use_tree.kind {
-            UseTreeKind::Simple(rename) =>
-                UseTreeKind::Simple(rename.map(|ident| fld.fold_ident(ident))),
+            UseTreeKind::Simple(rename, id1, id2) =>
+                UseTreeKind::Simple(rename.map(|ident| fld.fold_ident(ident)),
+                                    fld.new_id(id1), fld.new_id(id2)),
             UseTreeKind::Glob => UseTreeKind::Glob,
             UseTreeKind::Nested(items) => UseTreeKind::Nested(items.move_map(|(tree, id)| {
                 (fld.fold_use_tree(tree), fld.new_id(id))
@@ -370,14 +375,8 @@
             TyKind::Tup(tys) => TyKind::Tup(tys.move_map(|ty| fld.fold_ty(ty))),
             TyKind::Paren(ty) => TyKind::Paren(fld.fold_ty(ty)),
             TyKind::Path(qself, path) => {
-                let qself = qself.map(|QSelf { ty, path_span, position }| {
-                    QSelf {
-                        ty: fld.fold_ty(ty),
-                        path_span: fld.new_span(path_span),
-                        position,
-                    }
-                });
-                TyKind::Path(qself, fld.fold_path(path))
+                let (qself, path) = fld.fold_qpath(qself, path);
+                TyKind::Path(qself, path)
             }
             TyKind::Array(ty, length) => {
                 TyKind::Array(fld.fold_ty(ty), fld.fold_anon_const(length))
@@ -442,6 +441,19 @@
     }
 }
 
+pub fn noop_fold_qpath<T: Folder>(qself: Option<QSelf>,
+                                  path: Path,
+                                  fld: &mut T) -> (Option<QSelf>, Path) {
+    let qself = qself.map(|QSelf { ty, path_span, position }| {
+        QSelf {
+            ty: fld.fold_ty(ty),
+            path_span: fld.new_span(path_span),
+            position,
+        }
+    });
+    (qself, fld.fold_path(path))
+}
+
 pub fn noop_fold_path_parameters<T: Folder>(path_parameters: PathParameters, fld: &mut T)
                                             -> PathParameters
 {
@@ -1097,15 +1109,9 @@
                 PatKind::TupleStruct(folder.fold_path(pth),
                         pats.move_map(|x| folder.fold_pat(x)), ddpos)
             }
-            PatKind::Path(opt_qself, pth) => {
-                let opt_qself = opt_qself.map(|qself| {
-                    QSelf {
-                        ty: folder.fold_ty(qself.ty),
-                        path_span: folder.new_span(qself.path_span),
-                        position: qself.position,
-                    }
-                });
-                PatKind::Path(opt_qself, folder.fold_path(pth))
+            PatKind::Path(qself, pth) => {
+                let (qself, pth) = folder.fold_qpath(qself, pth);
+                PatKind::Path(qself, pth)
             }
             PatKind::Struct(pth, fields, etc) => {
                 let pth = folder.fold_path(pth);
@@ -1267,14 +1273,8 @@
                                 lim)
             }
             ExprKind::Path(qself, path) => {
-                let qself = qself.map(|QSelf { ty, path_span, position }| {
-                    QSelf {
-                        ty: folder.fold_ty(ty),
-                        path_span: folder.new_span(path_span),
-                        position,
-                    }
-                });
-                ExprKind::Path(qself, folder.fold_path(path))
+                let (qself, path) = folder.fold_qpath(qself, path);
+                ExprKind::Path(qself, path)
             }
             ExprKind::Break(opt_label, opt_expr) => {
                 ExprKind::Break(opt_label.map(|label| folder.fold_label(label)),
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index e981703..2ee14bd 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -25,6 +25,7 @@
 #![feature(const_atomic_usize_new)]
 #![feature(rustc_attrs)]
 #![feature(str_escape)]
+#![feature(crate_visibility_modifier)]
 
 #![recursion_limit="256"]
 
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index cceed58..9919d91 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -11,8 +11,7 @@
 use attr;
 use ast;
 use codemap::respan;
-use parse::common::SeqSep;
-use parse::PResult;
+use parse::{SeqSep, PResult};
 use parse::token::{self, Nonterminal};
 use parse::parser::{Parser, TokenType, PathStyle};
 use tokenstream::TokenStream;
@@ -28,7 +27,7 @@
 
 impl<'a> Parser<'a> {
     /// Parse attributes that appear before an item
-    pub fn parse_outer_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
+    crate fn parse_outer_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
         let mut attrs: Vec<ast::Attribute> = Vec::new();
         let mut just_parsed_doc_comment = false;
         loop {
@@ -139,7 +138,7 @@
         })
     }
 
-    pub fn parse_path_and_tokens(&mut self) -> PResult<'a, (ast::Path, TokenStream)> {
+    crate fn parse_path_and_tokens(&mut self) -> PResult<'a, (ast::Path, TokenStream)> {
         let meta = match self.token {
             token::Interpolated(ref nt) => match nt.0 {
                 Nonterminal::NtMeta(ref meta) => Some(meta.clone()),
@@ -160,7 +159,7 @@
     /// terminated by a semicolon.
 
     /// matches inner_attrs*
-    pub fn parse_inner_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
+    crate fn parse_inner_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
         let mut attrs: Vec<ast::Attribute> = vec![];
         loop {
             match self.token {
@@ -231,7 +230,7 @@
         Ok(ast::MetaItem { ident, node, span })
     }
 
-    pub fn parse_meta_item_kind(&mut self) -> PResult<'a, ast::MetaItemKind> {
+    crate fn parse_meta_item_kind(&mut self) -> PResult<'a, ast::MetaItemKind> {
         Ok(if self.eat(&token::Eq) {
             ast::MetaItemKind::NameValue(self.parse_unsuffixed_lit()?)
         } else if self.eat(&token::OpenDelim(token::Paren)) {
diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs
deleted file mode 100644
index fe931f7..0000000
--- a/src/libsyntax/parse/common.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Common routines shared by parser mods
-
-use parse::token;
-
-/// `SeqSep` : a sequence separator (token)
-/// and whether a trailing separator is allowed.
-pub struct SeqSep {
-    pub sep: Option<token::Token>,
-    pub trailing_sep_allowed: bool,
-}
-
-impl SeqSep {
-    pub fn trailing_allowed(t: token::Token) -> SeqSep {
-        SeqSep {
-            sep: Some(t),
-            trailing_sep_allowed: true,
-        }
-    }
-
-    pub fn none() -> SeqSep {
-        SeqSep {
-            sep: None,
-            trailing_sep_allowed: false,
-        }
-    }
-}
diff --git a/src/libsyntax/parse/lexer/comments.rs b/src/libsyntax/parse/lexer/comments.rs
index 7ead1ce..7da0d81 100644
--- a/src/libsyntax/parse/lexer/comments.rs
+++ b/src/libsyntax/parse/lexer/comments.rs
@@ -40,7 +40,7 @@
     pub pos: BytePos,
 }
 
-pub fn is_doc_comment(s: &str) -> bool {
+fn is_doc_comment(s: &str) -> bool {
     (s.starts_with("///") && super::is_doc_comment(s)) || s.starts_with("//!") ||
     (s.starts_with("/**") && is_block_doc_comment(s)) || s.starts_with("/*!")
 }
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index 04e180c..5353ff9 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -51,16 +51,16 @@
     pub ch: Option<char>,
     pub filemap: Lrc<syntax_pos::FileMap>,
     /// Stop reading src at this index.
-    pub end_src_index: usize,
+    end_src_index: usize,
     /// Whether to record new-lines and multibyte chars in filemap.
     /// This is only necessary the first time a filemap is lexed.
     /// If part of a filemap is being re-lexed, this should be set to false.
-    pub save_new_lines_and_multibyte: bool,
+    save_new_lines_and_multibyte: bool,
     // cached:
     peek_tok: token::Token,
     peek_span: Span,
     peek_span_src_raw: Span,
-    pub fatal_errs: Vec<DiagnosticBuilder<'a>>,
+    fatal_errs: Vec<DiagnosticBuilder<'a>>,
     // cache a direct reference to the source text, so that we don't have to
     // retrieve it via `self.filemap.src.as_ref().unwrap()` all the time.
     src: Lrc<String>,
@@ -70,7 +70,7 @@
     /// The raw source span which *does not* take `override_span` into account
     span_src_raw: Span,
     open_braces: Vec<(token::DelimToken, Span)>,
-    pub override_span: Option<Span>,
+    crate override_span: Option<Span>,
 }
 
 impl<'a> StringReader<'a> {
@@ -163,11 +163,9 @@
             sp: self.peek_span,
         }
     }
-}
 
-impl<'a> StringReader<'a> {
     /// For comments.rs, which hackily pokes into next_pos and ch
-    pub fn new_raw(sess: &'a ParseSess, filemap: Lrc<syntax_pos::FileMap>,
+    fn new_raw(sess: &'a ParseSess, filemap: Lrc<syntax_pos::FileMap>,
                    override_span: Option<Span>) -> Self {
         let mut sr = StringReader::new_raw_internal(sess, filemap, override_span);
         sr.bump();
@@ -240,17 +238,17 @@
         sr
     }
 
-    pub fn ch_is(&self, c: char) -> bool {
+    fn ch_is(&self, c: char) -> bool {
         self.ch == Some(c)
     }
 
     /// Report a fatal lexical error with a given span.
-    pub fn fatal_span(&self, sp: Span, m: &str) -> FatalError {
+    fn fatal_span(&self, sp: Span, m: &str) -> FatalError {
         self.sess.span_diagnostic.span_fatal(sp, m)
     }
 
     /// Report a lexical error with a given span.
-    pub fn err_span(&self, sp: Span, m: &str) {
+    fn err_span(&self, sp: Span, m: &str) {
         self.sess.span_diagnostic.span_err(sp, m)
     }
 
@@ -375,7 +373,7 @@
     /// Calls `f` with a string slice of the source text spanning from `start`
     /// up to but excluding `self.pos`, meaning the slice does not include
     /// the character `self.ch`.
-    pub fn with_str_from<T, F>(&self, start: BytePos, f: F) -> T
+    fn with_str_from<T, F>(&self, start: BytePos, f: F) -> T
         where F: FnOnce(&str) -> T
     {
         self.with_str_from_to(start, self.pos, f)
@@ -384,13 +382,13 @@
     /// Create a Name from a given offset to the current offset, each
     /// adjusted 1 towards each other (assumes that on either side there is a
     /// single-byte delimiter).
-    pub fn name_from(&self, start: BytePos) -> ast::Name {
+    fn name_from(&self, start: BytePos) -> ast::Name {
         debug!("taking an ident from {:?} to {:?}", start, self.pos);
         self.with_str_from(start, Symbol::intern)
     }
 
     /// As name_from, with an explicit endpoint.
-    pub fn name_from_to(&self, start: BytePos, end: BytePos) -> ast::Name {
+    fn name_from_to(&self, start: BytePos, end: BytePos) -> ast::Name {
         debug!("taking an ident from {:?} to {:?}", start, end);
         self.with_str_from_to(start, end, Symbol::intern)
     }
@@ -454,7 +452,7 @@
 
     /// Advance the StringReader by one character. If a newline is
     /// discovered, add it to the FileMap's list of line start offsets.
-    pub fn bump(&mut self) {
+    crate fn bump(&mut self) {
         let next_src_index = self.src_index(self.next_pos);
         if next_src_index < self.end_src_index {
             let next_ch = char_at(&self.src, next_src_index);
@@ -481,7 +479,7 @@
         }
     }
 
-    pub fn nextch(&self) -> Option<char> {
+    fn nextch(&self) -> Option<char> {
         let next_src_index = self.src_index(self.next_pos);
         if next_src_index < self.end_src_index {
             Some(char_at(&self.src, next_src_index))
@@ -490,11 +488,11 @@
         }
     }
 
-    pub fn nextch_is(&self, c: char) -> bool {
+    fn nextch_is(&self, c: char) -> bool {
         self.nextch() == Some(c)
     }
 
-    pub fn nextnextch(&self) -> Option<char> {
+    fn nextnextch(&self) -> Option<char> {
         let next_src_index = self.src_index(self.next_pos);
         if next_src_index < self.end_src_index {
             let next_next_src_index =
@@ -506,7 +504,7 @@
         None
     }
 
-    pub fn nextnextch_is(&self, c: char) -> bool {
+    fn nextnextch_is(&self, c: char) -> bool {
         self.nextnextch() == Some(c)
     }
 
@@ -1452,6 +1450,13 @@
                 self.bump();
                 let mut hash_count: u16 = 0;
                 while self.ch_is('#') {
+                    if hash_count == 65535 {
+                        let bpos = self.next_pos;
+                        self.fatal_span_(start_bpos,
+                                         bpos,
+                                         "too many `#` symbols: raw strings may be \
+                                         delimited by up to 65535 `#` symbols").raise();
+                    }
                     self.bump();
                     hash_count += 1;
                 }
@@ -1682,6 +1687,13 @@
         self.bump();
         let mut hash_count = 0;
         while self.ch_is('#') {
+            if hash_count == 65535 {
+                let bpos = self.next_pos;
+                self.fatal_span_(start_bpos,
+                                 bpos,
+                                 "too many `#` symbols: raw byte strings may be \
+                                 delimited by up to 65535 `#` symbols").raise();
+            }
             self.bump();
             hash_count += 1;
         }
@@ -1732,7 +1744,7 @@
 
 // This tests the character for the unicode property 'PATTERN_WHITE_SPACE' which
 // is guaranteed to be forward compatible. http://unicode.org/reports/tr31/#R3
-pub fn is_pattern_whitespace(c: Option<char>) -> bool {
+crate fn is_pattern_whitespace(c: Option<char>) -> bool {
     c.map_or(false, Pattern_White_Space)
 }
 
@@ -1747,14 +1759,14 @@
     in_range(c, '0', '9')
 }
 
-pub fn is_doc_comment(s: &str) -> bool {
+fn is_doc_comment(s: &str) -> bool {
     let res = (s.starts_with("///") && *s.as_bytes().get(3).unwrap_or(&b' ') != b'/') ||
               s.starts_with("//!");
     debug!("is {:?} a doc comment? {}", s, res);
     res
 }
 
-pub fn is_block_doc_comment(s: &str) -> bool {
+fn is_block_doc_comment(s: &str) -> bool {
     // Prevent `/**/` from being parsed as a doc comment
     let res = ((s.starts_with("/**") && *s.as_bytes().get(3).unwrap_or(&b' ') != b'*') ||
                s.starts_with("/*!")) && s.len() >= 5;
diff --git a/src/libsyntax/parse/lexer/tokentrees.rs b/src/libsyntax/parse/lexer/tokentrees.rs
index 278b8c9..36c220f 100644
--- a/src/libsyntax/parse/lexer/tokentrees.rs
+++ b/src/libsyntax/parse/lexer/tokentrees.rs
@@ -15,7 +15,7 @@
 
 impl<'a> StringReader<'a> {
     // Parse a stream of tokens into a list of `TokenTree`s, up to an `Eof`.
-    pub fn parse_all_token_trees(&mut self) -> PResult<'a, TokenStream> {
+    crate fn parse_all_token_trees(&mut self) -> PResult<'a, TokenStream> {
         let mut tts = Vec::new();
         while self.token != token::Eof {
             tts.push(self.parse_token_tree()?);
diff --git a/src/libsyntax/parse/lexer/unicode_chars.rs b/src/libsyntax/parse/lexer/unicode_chars.rs
index c5c2e02..a32b515 100644
--- a/src/libsyntax/parse/lexer/unicode_chars.rs
+++ b/src/libsyntax/parse/lexer/unicode_chars.rs
@@ -333,7 +333,7 @@
     ('=', "Equals Sign"),
     ('>', "Greater-Than Sign"), ];
 
-pub fn check_for_substitution<'a>(reader: &StringReader<'a>,
+crate fn check_for_substitution<'a>(reader: &StringReader<'a>,
                                   ch: char,
                                   err: &mut DiagnosticBuilder<'a>) -> bool {
     UNICODE_ARRAY
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 2549082..0050434 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -38,7 +38,6 @@
 pub mod token;
 pub mod attr;
 
-pub mod common;
 pub mod classify;
 
 /// Info about a parsing session.
@@ -51,7 +50,7 @@
     /// raw identifiers
     pub raw_identifier_spans: Lock<Vec<Span>>,
     /// The registered diagnostics codes
-    pub registered_diagnostics: Lock<ErrorMap>,
+    crate registered_diagnostics: Lock<ErrorMap>,
     // Spans where a `mod foo;` statement was included in a non-mod.rs file.
     // These are used to issue errors if the non_modrs_mods feature is not enabled.
     pub non_modrs_mods: Lock<Vec<(ast::Ident, Span)>>,
@@ -131,7 +130,7 @@
     new_parser_from_source_str(sess, name, source).parse_inner_attributes()
 }
 
-pub fn parse_expr_from_source_str(name: FileName, source: String, sess: &ParseSess)
+crate fn parse_expr_from_source_str(name: FileName, source: String, sess: &ParseSess)
                                       -> PResult<P<ast::Expr>> {
     new_parser_from_source_str(sess, name, source).parse_expr()
 }
@@ -140,17 +139,12 @@
 ///
 /// Returns `Ok(Some(item))` when successful, `Ok(None)` when no item was found, and `Err`
 /// when a syntax error occurred.
-pub fn parse_item_from_source_str(name: FileName, source: String, sess: &ParseSess)
+crate fn parse_item_from_source_str(name: FileName, source: String, sess: &ParseSess)
                                       -> PResult<Option<P<ast::Item>>> {
     new_parser_from_source_str(sess, name, source).parse_item()
 }
 
-pub fn parse_meta_from_source_str(name: FileName, source: String, sess: &ParseSess)
-                                      -> PResult<ast::MetaItem> {
-    new_parser_from_source_str(sess, name, source).parse_meta_item()
-}
-
-pub fn parse_stmt_from_source_str(name: FileName, source: String, sess: &ParseSess)
+crate fn parse_stmt_from_source_str(name: FileName, source: String, sess: &ParseSess)
                                       -> PResult<Option<ast::Stmt>> {
     new_parser_from_source_str(sess, name, source).parse_stmt()
 }
@@ -178,7 +172,7 @@
 /// Given a session, a crate config, a path, and a span, add
 /// the file at the given path to the codemap, and return a parser.
 /// On an error, use the given span as the source of the problem.
-pub fn new_sub_parser_from_file<'a>(sess: &'a ParseSess,
+crate fn new_sub_parser_from_file<'a>(sess: &'a ParseSess,
                                     path: &Path,
                                     directory_ownership: DirectoryOwnership,
                                     module_name: Option<String>,
@@ -190,7 +184,7 @@
 }
 
 /// Given a filemap and config, return a parser
-pub fn filemap_to_parser(sess: & ParseSess, filemap: Lrc<FileMap>) -> Parser {
+fn filemap_to_parser(sess: & ParseSess, filemap: Lrc<FileMap>) -> Parser {
     let end_pos = filemap.end_pos;
     let mut parser = stream_to_parser(sess, filemap_to_stream(sess, filemap, None));
 
@@ -243,7 +237,7 @@
 /// Rather than just accepting/rejecting a given literal, unescapes it as
 /// well. Can take any slice prefixed by a character escape. Returns the
 /// character and the number of characters consumed.
-pub fn char_lit(lit: &str, diag: Option<(Span, &Handler)>) -> (char, isize) {
+fn char_lit(lit: &str, diag: Option<(Span, &Handler)>) -> (char, isize) {
     use std::char;
 
     // Handle non-escaped chars first.
@@ -300,7 +294,7 @@
 
 /// Parse a string representing a string literal into its final form. Does
 /// unescaping.
-pub fn str_lit(lit: &str, diag: Option<(Span, &Handler)>) -> String {
+fn str_lit(lit: &str, diag: Option<(Span, &Handler)>) -> String {
     debug!("str_lit: given {}", lit.escape_default());
     let mut res = String::with_capacity(lit.len());
 
@@ -369,7 +363,7 @@
 
 /// Parse a string representing a raw string literal into its final form. The
 /// only operation this does is convert embedded CRLF into a single LF.
-pub fn raw_str_lit(lit: &str) -> String {
+fn raw_str_lit(lit: &str) -> String {
     debug!("raw_str_lit: given {}", lit.escape_default());
     let mut res = String::with_capacity(lit.len());
 
@@ -406,7 +400,7 @@
     }
 }
 
-pub fn lit_token(lit: token::Lit, suf: Option<Symbol>, diag: Option<(Span, &Handler)>)
+crate fn lit_token(lit: token::Lit, suf: Option<Symbol>, diag: Option<(Span, &Handler)>)
                  -> (bool /* suffix illegal? */, Option<ast::LitKind>) {
     use ast::LitKind;
 
@@ -476,7 +470,7 @@
         }
     })
 }
-pub fn float_lit(s: &str, suffix: Option<Symbol>, diag: Option<(Span, &Handler)>)
+fn float_lit(s: &str, suffix: Option<Symbol>, diag: Option<(Span, &Handler)>)
                  -> Option<ast::LitKind> {
     debug!("float_lit: {:?}, {:?}", s, suffix);
     // FIXME #2252: bounds checking float literals is deferred until trans
@@ -485,7 +479,7 @@
 }
 
 /// Parse a string representing a byte literal into its final form. Similar to `char_lit`
-pub fn byte_lit(lit: &str) -> (u8, usize) {
+fn byte_lit(lit: &str) -> (u8, usize) {
     let err = |i| format!("lexer accepted invalid byte literal {} step {}", lit, i);
 
     if lit.len() == 1 {
@@ -516,7 +510,7 @@
     }
 }
 
-pub fn byte_str_lit(lit: &str) -> Lrc<Vec<u8>> {
+fn byte_str_lit(lit: &str) -> Lrc<Vec<u8>> {
     let mut res = Vec::with_capacity(lit.len());
 
     let error = |i| format!("lexer should have rejected {} at {}", lit, i);
@@ -575,7 +569,7 @@
     Lrc::new(res)
 }
 
-pub fn integer_lit(s: &str, suffix: Option<Symbol>, diag: Option<(Span, &Handler)>)
+fn integer_lit(s: &str, suffix: Option<Symbol>, diag: Option<(Span, &Handler)>)
                    -> Option<ast::LitKind> {
     // s can only be ascii, byte indexing is fine
 
@@ -1136,3 +1130,26 @@
         });
     }
 }
+
+/// `SeqSep` : a sequence separator (token)
+/// and whether a trailing separator is allowed.
+pub struct SeqSep {
+    pub sep: Option<token::Token>,
+    pub trailing_sep_allowed: bool,
+}
+
+impl SeqSep {
+    pub fn trailing_allowed(t: token::Token) -> SeqSep {
+        SeqSep {
+            sep: Some(t),
+            trailing_sep_allowed: true,
+        }
+    }
+
+    pub fn none() -> SeqSep {
+        SeqSep {
+            sep: None,
+            trailing_sep_allowed: false,
+        }
+    }
+}
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index f6692a3..1735951 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -23,7 +23,7 @@
 use ast::{ForeignItem, ForeignItemKind, FunctionRetTy};
 use ast::GenericParam;
 use ast::{Ident, ImplItem, IsAuto, Item, ItemKind};
-use ast::{Label, Lifetime, LifetimeDef, Lit, LitKind, UintTy};
+use ast::{Label, Lifetime, LifetimeDef, Lit, LitKind};
 use ast::Local;
 use ast::MacStmtStyle;
 use ast::{Mac, Mac_, MacDelimiter};
@@ -44,8 +44,7 @@
 use codemap::{self, CodeMap, Spanned, respan};
 use syntax_pos::{self, Span, MultiSpan, BytePos, FileName, DUMMY_SP};
 use errors::{self, Applicability, DiagnosticBuilder};
-use parse::{self, classify, token};
-use parse::common::SeqSep;
+use parse::{self, SeqSep, classify, token};
 use parse::lexer::TokenAndSpan;
 use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
 use parse::{new_sub_parser_from_file, ParseSess, Directory, DirectoryOwnership};
@@ -64,7 +63,7 @@
 use std::slice;
 
 bitflags! {
-    pub struct Restrictions: u8 {
+    struct Restrictions: u8 {
         const STMT_EXPR         = 1 << 0;
         const NO_STRUCT_LITERAL = 1 << 1;
     }
@@ -96,13 +95,13 @@
 }
 
 #[derive(Clone, Copy, Debug, PartialEq)]
-pub enum SemiColonMode {
+enum SemiColonMode {
     Break,
     Ignore,
 }
 
 #[derive(Clone, Copy, Debug, PartialEq)]
-pub enum BlockMode {
+enum BlockMode {
     Break,
     Ignore,
 }
@@ -223,22 +222,22 @@
     /// the span of the current token:
     pub span: Span,
     /// the span of the previous token:
-    pub meta_var_span: Option<Span>,
+    meta_var_span: Option<Span>,
     pub prev_span: Span,
     /// the previous token kind
     prev_token_kind: PrevTokenKind,
-    pub restrictions: Restrictions,
+    restrictions: Restrictions,
     /// Used to determine the path to externally loaded source files
-    pub directory: Directory<'a>,
+    crate directory: Directory<'a>,
     /// Whether to parse sub-modules in other files.
     pub recurse_into_file_modules: bool,
     /// Name of the root module this parser originated from. If `None`, then the
     /// name is not known. This does not change while the parser is descending
     /// into modules, and sub-parsers have new values for this name.
     pub root_module_name: Option<String>,
-    pub expected_tokens: Vec<TokenType>,
+    crate expected_tokens: Vec<TokenType>,
     token_cursor: TokenCursor,
-    pub desugar_doc_comments: bool,
+    desugar_doc_comments: bool,
     /// Whether we should configure out of line modules as we parse.
     pub cfg_mods: bool,
 }
@@ -377,7 +376,7 @@
 }
 
 #[derive(PartialEq, Eq, Clone)]
-pub enum TokenType {
+crate enum TokenType {
     Token(token::Token),
     Keyword(keywords::Keyword),
     Operator,
@@ -390,7 +389,7 @@
 impl TokenType {
     fn to_string(&self) -> String {
         match *self {
-            TokenType::Token(ref t) => format!("`{}`", Parser::token_to_string(t)),
+            TokenType::Token(ref t) => format!("`{}`", pprust::token_to_string(t)),
             TokenType::Keyword(kw) => format!("`{}`", kw.name()),
             TokenType::Operator => "an operator".to_string(),
             TokenType::Lifetime => "lifetime".to_string(),
@@ -413,8 +412,8 @@
 
 /// Information about the path to a module.
 pub struct ModulePath {
-    pub name: String,
-    pub path_exists: bool,
+    name: String,
+    path_exists: bool,
     pub result: Result<ModulePathSuccess, Error>,
 }
 
@@ -424,11 +423,6 @@
     warn: bool,
 }
 
-pub struct ModulePathError {
-    pub err_msg: String,
-    pub help_msg: String,
-}
-
 pub enum Error {
     FileNotFoundForModule {
         mod_name: String,
@@ -446,7 +440,7 @@
 }
 
 impl Error {
-    pub fn span_err<S: Into<MultiSpan>>(self,
+    fn span_err<S: Into<MultiSpan>>(self,
                                         sp: S,
                                         handler: &errors::Handler) -> DiagnosticBuilder {
         match self {
@@ -489,7 +483,7 @@
 }
 
 #[derive(Debug)]
-pub enum LhsExpr {
+enum LhsExpr {
     NotYetParsed,
     AttributesParsed(ThinVec<Attribute>),
     AlreadyParsed(P<Expr>),
@@ -596,17 +590,12 @@
         next
     }
 
-    /// Convert a token to a string using self's reader
-    pub fn token_to_string(token: &token::Token) -> String {
-        pprust::token_to_string(token)
-    }
-
     /// Convert the current token to a string using self's reader
     pub fn this_token_to_string(&self) -> String {
-        Parser::token_to_string(&self.token)
+        pprust::token_to_string(&self.token)
     }
 
-    pub fn token_descr(&self) -> Option<&'static str> {
+    fn token_descr(&self) -> Option<&'static str> {
         Some(match &self.token {
             t if t.is_special_ident() => "reserved identifier",
             t if t.is_used_keyword() => "keyword",
@@ -615,7 +604,7 @@
         })
     }
 
-    pub fn this_token_descr(&self) -> String {
+    fn this_token_descr(&self) -> String {
         if let Some(prefix) = self.token_descr() {
             format!("{} `{}`", prefix, self.this_token_to_string())
         } else {
@@ -623,12 +612,12 @@
         }
     }
 
-    pub fn unexpected_last<T>(&self, t: &token::Token) -> PResult<'a, T> {
-        let token_str = Parser::token_to_string(t);
+    fn unexpected_last<T>(&self, t: &token::Token) -> PResult<'a, T> {
+        let token_str = pprust::token_to_string(t);
         Err(self.span_fatal(self.prev_span, &format!("unexpected token: `{}`", token_str)))
     }
 
-    pub fn unexpected<T>(&mut self) -> PResult<'a, T> {
+    crate fn unexpected<T>(&mut self) -> PResult<'a, T> {
         match self.expect_one_of(&[], &[]) {
             Err(e) => Err(e),
             Ok(_) => unreachable!(),
@@ -643,7 +632,7 @@
                 self.bump();
                 Ok(())
             } else {
-                let token_str = Parser::token_to_string(t);
+                let token_str = pprust::token_to_string(t);
                 let this_token_str = self.this_token_to_string();
                 let mut err = self.fatal(&format!("expected `{}`, found `{}`",
                                                   token_str,
@@ -652,14 +641,14 @@
                 Err(err)
             }
         } else {
-            self.expect_one_of(unsafe { slice::from_raw_parts(t, 1) }, &[])
+            self.expect_one_of(slice::from_ref(t), &[])
         }
     }
 
     /// Expect next token to be edible or inedible token.  If edible,
     /// then consume it; if inedible, then return without consuming
     /// anything.  Signal a fatal error if next token is unexpected.
-    pub fn expect_one_of(&mut self,
+    fn expect_one_of(&mut self,
                          edible: &[token::Token],
                          inedible: &[token::Token]) -> PResult<'a,  ()>{
         fn tokens_to_string(tokens: &[TokenType]) -> String {
@@ -804,7 +793,7 @@
     ///
     /// This method will automatically add `tok` to `expected_tokens` if `tok` is not
     /// encountered.
-    pub fn check(&mut self, tok: &token::Token) -> bool {
+    fn check(&mut self, tok: &token::Token) -> bool {
         let is_present = self.token == *tok;
         if !is_present { self.expected_tokens.push(TokenType::Token(tok.clone())); }
         is_present
@@ -818,7 +807,7 @@
         is_present
     }
 
-    pub fn check_keyword(&mut self, kw: keywords::Keyword) -> bool {
+    fn check_keyword(&mut self, kw: keywords::Keyword) -> bool {
         self.expected_tokens.push(TokenType::Keyword(kw));
         self.token.is_keyword(kw)
     }
@@ -834,7 +823,7 @@
         }
     }
 
-    pub fn eat_keyword_noexpect(&mut self, kw: keywords::Keyword) -> bool {
+    fn eat_keyword_noexpect(&mut self, kw: keywords::Keyword) -> bool {
         if self.token.is_keyword(kw) {
             self.bump();
             true
@@ -846,7 +835,7 @@
     /// If the given word is not a keyword, signal an error.
     /// If the next token is not the given word, signal an error.
     /// Otherwise, eat it.
-    pub fn expect_keyword(&mut self, kw: keywords::Keyword) -> PResult<'a, ()> {
+    fn expect_keyword(&mut self, kw: keywords::Keyword) -> PResult<'a, ()> {
         if !self.eat_keyword(kw) {
             self.unexpected()
         } else {
@@ -881,6 +870,40 @@
         }
     }
 
+    /// Expect and consume a `+`. if `+=` is seen, replace it with a `=`
+    /// and continue. If a `+` is not seen, return false.
+    ///
+    /// This is using when token splitting += into +.
+    /// See issue 47856 for an example of when this may occur.
+    fn eat_plus(&mut self) -> bool {
+        self.expected_tokens.push(TokenType::Token(token::BinOp(token::Plus)));
+        match self.token {
+            token::BinOp(token::Plus) => {
+                self.bump();
+                true
+            }
+            token::BinOpEq(token::Plus) => {
+                let span = self.span.with_lo(self.span.lo() + BytePos(1));
+                self.bump_with(token::Eq, span);
+                true
+            }
+            _ => false,
+        }
+    }
+
+
+    /// Checks to see if the next token is either `+` or `+=`.
+    /// Otherwise returns false.
+    fn check_plus(&mut self) -> bool {
+        if self.token.is_like_plus() {
+            true
+        }
+        else {
+            self.expected_tokens.push(TokenType::Token(token::BinOp(token::Plus)));
+            false
+        }
+    }
+
     /// Expect and consume an `&`. If `&&` is seen, replace it with a single
     /// `&` and continue. If an `&` is not seen, signal an error.
     fn expect_and(&mut self) -> PResult<'a, ()> {
@@ -915,7 +938,7 @@
         }
     }
 
-    pub fn expect_no_suffix(&self, sp: Span, kind: &str, suffix: Option<ast::Name>) {
+    fn expect_no_suffix(&self, sp: Span, kind: &str, suffix: Option<ast::Name>) {
         match suffix {
             None => {/* everything ok */}
             Some(suf) => {
@@ -960,7 +983,7 @@
     /// Expect and consume a GT. if a >> is seen, replace it
     /// with a single > and continue. If a GT is not seen,
     /// signal an error.
-    pub fn expect_gt(&mut self) -> PResult<'a, ()> {
+    fn expect_gt(&mut self) -> PResult<'a, ()> {
         self.expected_tokens.push(TokenType::Token(token::Gt));
         match self.token {
             token::Gt => {
@@ -983,83 +1006,9 @@
         }
     }
 
-    pub fn parse_seq_to_before_gt_or_return<T, F>(&mut self,
-                                                  sep: Option<token::Token>,
-                                                  mut f: F)
-                                                  -> PResult<'a, (Vec<T>, bool)>
-        where F: FnMut(&mut Parser<'a>) -> PResult<'a, Option<T>>,
-    {
-        let mut v = Vec::new();
-        // This loop works by alternating back and forth between parsing types
-        // and commas.  For example, given a string `A, B,>`, the parser would
-        // first parse `A`, then a comma, then `B`, then a comma. After that it
-        // would encounter a `>` and stop. This lets the parser handle trailing
-        // commas in generic parameters, because it can stop either after
-        // parsing a type or after parsing a comma.
-        for i in 0.. {
-            if self.check(&token::Gt)
-                || self.token == token::BinOp(token::Shr)
-                || self.token == token::Ge
-                || self.token == token::BinOpEq(token::Shr) {
-                break;
-            }
-
-            if i % 2 == 0 {
-                match f(self)? {
-                    Some(result) => v.push(result),
-                    None => return Ok((v, true))
-                }
-            } else {
-                if let Some(t) = sep.as_ref() {
-                    self.expect(t)?;
-                }
-
-            }
-        }
-        return Ok((v, false));
-    }
-
-    /// Parse a sequence bracketed by '<' and '>', stopping
-    /// before the '>'.
-    pub fn parse_seq_to_before_gt<T, F>(&mut self,
-                                        sep: Option<token::Token>,
-                                        mut f: F)
-                                        -> PResult<'a, Vec<T>> where
-        F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
-    {
-        let (result, returned) = self.parse_seq_to_before_gt_or_return(sep,
-                                                                       |p| Ok(Some(f(p)?)))?;
-        assert!(!returned);
-        return Ok(result);
-    }
-
-    pub fn parse_seq_to_gt<T, F>(&mut self,
-                                 sep: Option<token::Token>,
-                                 f: F)
-                                 -> PResult<'a, Vec<T>> where
-        F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
-    {
-        let v = self.parse_seq_to_before_gt(sep, f)?;
-        self.expect_gt()?;
-        return Ok(v);
-    }
-
-    pub fn parse_seq_to_gt_or_return<T, F>(&mut self,
-                                           sep: Option<token::Token>,
-                                           f: F)
-                                           -> PResult<'a, (Vec<T>, bool)> where
-        F: FnMut(&mut Parser<'a>) -> PResult<'a, Option<T>>,
-    {
-        let (v, returned) = self.parse_seq_to_before_gt_or_return(sep, f)?;
-        if !returned {
-            self.expect_gt()?;
-        }
-        return Ok((v, returned));
-    }
-
     /// Eat and discard tokens until one of `kets` is encountered. Respects token trees,
     /// passes through any errors encountered. Used for error recovery.
-    pub fn eat_to_tokens(&mut self, kets: &[&token::Token]) {
+    fn eat_to_tokens(&mut self, kets: &[&token::Token]) {
         let handler = self.diagnostic();
 
         if let Err(ref mut err) = self.parse_seq_to_before_tokens(kets,
@@ -1088,7 +1037,7 @@
     /// Parse a sequence, not including the closing delimiter. The function
     /// f must consume tokens until reaching the next separator or
     /// closing bracket.
-    pub fn parse_seq_to_before_end<T, F>(&mut self,
+    fn parse_seq_to_before_end<T, F>(&mut self,
                                          ket: &token::Token,
                                          sep: SeqSep,
                                          f: F)
@@ -1108,7 +1057,12 @@
     {
         let mut first: bool = true;
         let mut v = vec![];
-        while !kets.contains(&&self.token) {
+        while !kets.iter().any(|k| {
+                match expect {
+                    TokenExpectType::Expect => self.check(k),
+                    TokenExpectType::NoExpect => self.token == **k,
+                }
+            }) {
             match self.token {
                 token::CloseDelim(..) | token::Eof => break,
                 _ => {}
@@ -1158,7 +1112,7 @@
     /// Parse a sequence, including the closing delimiter. The function
     /// f must consume tokens until reaching the next separator or
     /// closing bracket.
-    pub fn parse_unspanned_seq<T, F>(&mut self,
+    fn parse_unspanned_seq<T, F>(&mut self,
                                      bra: &token::Token,
                                      ket: &token::Token,
                                      sep: SeqSep,
@@ -1174,24 +1128,6 @@
         Ok(result)
     }
 
-    // NB: Do not use this function unless you actually plan to place the
-    // spanned list in the AST.
-    pub fn parse_seq<T, F>(&mut self,
-                           bra: &token::Token,
-                           ket: &token::Token,
-                           sep: SeqSep,
-                           f: F)
-                           -> PResult<'a, Spanned<Vec<T>>> where
-        F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
-    {
-        let lo = self.span;
-        self.expect(bra)?;
-        let result = self.parse_seq_to_before_end(ket, sep, f)?;
-        let hi = self.span;
-        self.bump();
-        Ok(respan(lo.to(hi), result))
-    }
-
     /// Advance the parser by one token
     pub fn bump(&mut self) {
         if self.prev_token_kind == PrevTokenKind::Eof {
@@ -1222,7 +1158,7 @@
 
     /// Advance the parser using provided token as a next one. Use this when
     /// consuming a part of a token. For example a single `<` from `<<`.
-    pub fn bump_with(&mut self, next: token::Token, span: Span) {
+    fn bump_with(&mut self, next: token::Token, span: Span) {
         self.prev_span = self.span.with_hi(span.lo());
         // It would be incorrect to record the kind of the current token, but
         // fortunately for tokens currently using `bump_with`, the
@@ -1265,10 +1201,10 @@
     pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
         self.sess.span_diagnostic.struct_span_fatal(sp, m)
     }
-    pub fn span_fatal_err<S: Into<MultiSpan>>(&self, sp: S, err: Error) -> DiagnosticBuilder<'a> {
+    fn span_fatal_err<S: Into<MultiSpan>>(&self, sp: S, err: Error) -> DiagnosticBuilder<'a> {
         err.span_err(sp, self.diagnostic())
     }
-    pub fn span_fatal_help<S: Into<MultiSpan>>(&self,
+    fn span_fatal_help<S: Into<MultiSpan>>(&self,
                                             sp: S,
                                             m: &str,
                                             help: &str) -> DiagnosticBuilder<'a> {
@@ -1276,30 +1212,19 @@
         err.help(help);
         err
     }
-    pub fn bug(&self, m: &str) -> ! {
+    fn bug(&self, m: &str) -> ! {
         self.sess.span_diagnostic.span_bug(self.span, m)
     }
-    pub fn warn(&self, m: &str) {
-        self.sess.span_diagnostic.span_warn(self.span, m)
-    }
-    pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, m: &str) {
-        self.sess.span_diagnostic.span_warn(sp, m)
-    }
-    pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) {
+    fn span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) {
         self.sess.span_diagnostic.span_err(sp, m)
     }
-    pub fn struct_span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
+    fn struct_span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> {
         self.sess.span_diagnostic.struct_span_err(sp, m)
     }
-    pub fn span_err_help<S: Into<MultiSpan>>(&self, sp: S, m: &str, h: &str) {
-        let mut err = self.sess.span_diagnostic.mut_span_err(sp, m);
-        err.help(h);
-        err.emit();
-    }
-    pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> ! {
+    crate fn span_bug<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> ! {
         self.sess.span_diagnostic.span_bug(sp, m)
     }
-    pub fn abort_if_errors(&self) {
+    crate fn abort_if_errors(&self) {
         self.sess.span_diagnostic.abort_if_errors();
     }
 
@@ -1307,20 +1232,20 @@
         self.sess.span_diagnostic.cancel(err)
     }
 
-    pub fn diagnostic(&self) -> &'a errors::Handler {
+    crate fn diagnostic(&self) -> &'a errors::Handler {
         &self.sess.span_diagnostic
     }
 
     /// Is the current token one of the keywords that signals a bare function
     /// type?
-    pub fn token_is_bare_fn_keyword(&mut self) -> bool {
+    fn token_is_bare_fn_keyword(&mut self) -> bool {
         self.check_keyword(keywords::Fn) ||
             self.check_keyword(keywords::Unsafe) ||
             self.check_keyword(keywords::Extern) && self.is_extern_non_path()
     }
 
     /// parse a TyKind::BareFn type:
-    pub fn parse_ty_bare_fn(&mut self, generic_params: Vec<GenericParam>)
+    fn parse_ty_bare_fn(&mut self, generic_params: Vec<GenericParam>)
                             -> PResult<'a, TyKind> {
         /*
 
@@ -1512,7 +1437,7 @@
 
             if ts.len() == 1 && !last_comma {
                 let ty = ts.into_iter().nth(0).unwrap().into_inner();
-                let maybe_bounds = allow_plus && self.token == token::BinOp(token::Plus);
+                let maybe_bounds = allow_plus && self.token.is_like_plus();
                 match ty.node {
                     // `(TY_BOUND_NOPAREN) + BOUND + ...`.
                     TyKind::Path(None, ref path) if maybe_bounds => {
@@ -1581,7 +1506,7 @@
                 self.parse_ty_bare_fn(lifetime_defs)?
             } else {
                 let path = self.parse_path(PathStyle::Type)?;
-                let parse_plus = allow_plus && self.check(&token::BinOp(token::Plus));
+                let parse_plus = allow_plus && self.check_plus();
                 self.parse_remaining_bounds(lifetime_defs, path, lo, parse_plus)?
             }
         } else if self.eat_keyword(keywords::Impl) {
@@ -1598,7 +1523,7 @@
             impl_dyn_multi = bounds.len() > 1 || self.prev_token_kind == PrevTokenKind::Plus;
             TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn)
         } else if self.check(&token::Question) ||
-                  self.check_lifetime() && self.look_ahead(1, |t| t == &token::BinOp(token::Plus)) {
+                  self.check_lifetime() && self.look_ahead(1, |t| t.is_like_plus()) {
             // Bound list (trait object type)
             TyKind::TraitObject(self.parse_ty_param_bounds_common(allow_plus)?,
                                 TraitObjectSyntax::None)
@@ -1618,7 +1543,7 @@
                 // Just a type path or bound list (trait object type) starting with a trait.
                 //   `Type`
                 //   `Trait1 + Trait2 + 'a`
-                if allow_plus && self.check(&token::BinOp(token::Plus)) {
+                if allow_plus && self.check_plus() {
                     self.parse_remaining_bounds(Vec::new(), path, lo, true)?
                 } else {
                     TyKind::Path(None, path)
@@ -1645,7 +1570,7 @@
         let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_span));
         let mut bounds = vec![TraitTyParamBound(poly_trait_ref, TraitBoundModifier::None)];
         if parse_plus {
-            self.bump(); // `+`
+            self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded
             bounds.append(&mut self.parse_ty_param_bounds()?);
         }
         Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
@@ -1666,7 +1591,7 @@
 
     fn maybe_recover_from_bad_type_plus(&mut self, allow_plus: bool, ty: &Ty) -> PResult<'a, ()> {
         // Do not add `+` to expected tokens.
-        if !allow_plus || self.token != token::BinOp(token::Plus) {
+        if !allow_plus || !self.token.is_like_plus() {
             return Ok(())
         }
 
@@ -1747,7 +1672,7 @@
         return Ok(TyKind::Rptr(opt_lifetime, MutTy { ty: ty, mutbl: mutbl }));
     }
 
-    pub fn parse_ptr(&mut self) -> PResult<'a, MutTy> {
+    fn parse_ptr(&mut self) -> PResult<'a, MutTy> {
         let mutbl = if self.eat_keyword(keywords::Mut) {
             Mutability::Mutable
         } else if self.eat_keyword(keywords::Const) {
@@ -1780,7 +1705,7 @@
 
     /// This version of parse arg doesn't necessarily require
     /// identifier names.
-    pub fn parse_arg_general(&mut self, require_name: bool) -> PResult<'a, Arg> {
+    fn parse_arg_general(&mut self, require_name: bool) -> PResult<'a, Arg> {
         maybe_whole!(self, NtArg, |x| x);
 
         let (pat, ty) = if require_name || self.is_named_argument() {
@@ -1810,12 +1735,12 @@
     }
 
     /// Parse a single function argument
-    pub fn parse_arg(&mut self) -> PResult<'a, Arg> {
+    crate fn parse_arg(&mut self) -> PResult<'a, Arg> {
         self.parse_arg_general(true)
     }
 
     /// Parse an argument in a lambda header e.g. |arg, arg|
-    pub fn parse_fn_block_arg(&mut self) -> PResult<'a, Arg> {
+    fn parse_fn_block_arg(&mut self) -> PResult<'a, Arg> {
         let pat = self.parse_pat()?;
         let t = if self.eat(&token::Colon) {
             self.parse_ty()?
@@ -1833,7 +1758,7 @@
         })
     }
 
-    pub fn maybe_parse_fixed_length_of_vec(&mut self) -> PResult<'a, Option<P<ast::Expr>>> {
+    fn maybe_parse_fixed_length_of_vec(&mut self) -> PResult<'a, Option<P<ast::Expr>>> {
         if self.eat(&token::Semi) {
             Ok(Some(self.parse_expr()?))
         } else {
@@ -1842,7 +1767,7 @@
     }
 
     /// Matches token_lit = LIT_INTEGER | ...
-    pub fn parse_lit_token(&mut self) -> PResult<'a, LitKind> {
+    fn parse_lit_token(&mut self) -> PResult<'a, LitKind> {
         let out = match self.token {
             token::Interpolated(ref nt) => match nt.0 {
                 token::NtExpr(ref v) | token::NtLiteral(ref v) => match v.node {
@@ -1870,7 +1795,7 @@
     }
 
     /// Matches lit = true | false | token_lit
-    pub fn parse_lit(&mut self) -> PResult<'a, Lit> {
+    crate fn parse_lit(&mut self) -> PResult<'a, Lit> {
         let lo = self.span;
         let lit = if self.eat_keyword(keywords::True) {
             LitKind::Bool(true)
@@ -1884,7 +1809,7 @@
     }
 
     /// matches '-' lit | lit (cf. ast_validation::AstValidator::check_expr_within_pat)
-    pub fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> {
+    crate fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> {
         maybe_whole_expr!(self);
 
         let minus_lo = self.span;
@@ -1903,7 +1828,7 @@
         }
     }
 
-    pub fn parse_path_segment_ident(&mut self) -> PResult<'a, ast::Ident> {
+    fn parse_path_segment_ident(&mut self) -> PResult<'a, ast::Ident> {
         match self.token {
             token::Ident(ident, _) if self.token.is_path_segment_keyword() => {
                 let span = self.span;
@@ -1965,7 +1890,7 @@
         self.parse_path_common(style, true)
     }
 
-    pub fn parse_path_common(&mut self, style: PathStyle, enable_warning: bool)
+    crate fn parse_path_common(&mut self, style: PathStyle, enable_warning: bool)
                              -> PResult<'a, ast::Path> {
         maybe_whole!(self, NtPath, |path| {
             if style == PathStyle::Mod &&
@@ -2075,13 +2000,13 @@
         })
     }
 
-    pub fn check_lifetime(&mut self) -> bool {
+    crate fn check_lifetime(&mut self) -> bool {
         self.expected_tokens.push(TokenType::Lifetime);
         self.token.is_lifetime()
     }
 
     /// Parse single lifetime 'a or panic.
-    pub fn expect_lifetime(&mut self) -> Lifetime {
+    crate fn expect_lifetime(&mut self) -> Lifetime {
         if let Some(ident) = self.token.lifetime() {
             let span = self.span;
             self.bump();
@@ -2110,7 +2035,7 @@
         }
     }
 
-    pub fn parse_field_name(&mut self) -> PResult<'a, Ident> {
+    fn parse_field_name(&mut self) -> PResult<'a, Ident> {
         if let token::Literal(token::Integer(name), None) = self.token {
             self.bump();
             Ok(Ident::new(name, self.prev_span))
@@ -2120,7 +2045,7 @@
     }
 
     /// Parse ident (COLON expr)?
-    pub fn parse_field(&mut self) -> PResult<'a, Field> {
+    fn parse_field(&mut self) -> PResult<'a, Field> {
         let attrs = self.parse_outer_attributes()?;
         let lo = self.span;
 
@@ -2146,27 +2071,27 @@
         })
     }
 
-    pub fn mk_expr(&mut self, span: Span, node: ExprKind, attrs: ThinVec<Attribute>) -> P<Expr> {
+    fn mk_expr(&mut self, span: Span, node: ExprKind, attrs: ThinVec<Attribute>) -> P<Expr> {
         P(Expr { node, span, attrs, id: ast::DUMMY_NODE_ID })
     }
 
-    pub fn mk_unary(&mut self, unop: ast::UnOp, expr: P<Expr>) -> ast::ExprKind {
+    fn mk_unary(&mut self, unop: ast::UnOp, expr: P<Expr>) -> ast::ExprKind {
         ExprKind::Unary(unop, expr)
     }
 
-    pub fn mk_binary(&mut self, binop: ast::BinOp, lhs: P<Expr>, rhs: P<Expr>) -> ast::ExprKind {
+    fn mk_binary(&mut self, binop: ast::BinOp, lhs: P<Expr>, rhs: P<Expr>) -> ast::ExprKind {
         ExprKind::Binary(binop, lhs, rhs)
     }
 
-    pub fn mk_call(&mut self, f: P<Expr>, args: Vec<P<Expr>>) -> ast::ExprKind {
+    fn mk_call(&mut self, f: P<Expr>, args: Vec<P<Expr>>) -> ast::ExprKind {
         ExprKind::Call(f, args)
     }
 
-    pub fn mk_index(&mut self, expr: P<Expr>, idx: P<Expr>) -> ast::ExprKind {
+    fn mk_index(&mut self, expr: P<Expr>, idx: P<Expr>) -> ast::ExprKind {
         ExprKind::Index(expr, idx)
     }
 
-    pub fn mk_range(&mut self,
+    fn mk_range(&mut self,
                     start: Option<P<Expr>>,
                     end: Option<P<Expr>>,
                     limits: RangeLimits)
@@ -2178,12 +2103,12 @@
         }
     }
 
-    pub fn mk_assign_op(&mut self, binop: ast::BinOp,
+    fn mk_assign_op(&mut self, binop: ast::BinOp,
                         lhs: P<Expr>, rhs: P<Expr>) -> ast::ExprKind {
         ExprKind::AssignOp(binop, lhs, rhs)
     }
 
-    pub fn mk_mac_expr(&mut self, span: Span, m: Mac_, attrs: ThinVec<Attribute>) -> P<Expr> {
+    fn mk_mac_expr(&mut self, span: Span, m: Mac_, attrs: ThinVec<Attribute>) -> P<Expr> {
         P(Expr {
             id: ast::DUMMY_NODE_ID,
             node: ExprKind::Mac(codemap::Spanned {node: m, span: span}),
@@ -2192,21 +2117,6 @@
         })
     }
 
-    pub fn mk_lit_u32(&mut self, i: u32, attrs: ThinVec<Attribute>) -> P<Expr> {
-        let span = &self.span;
-        let lv_lit = P(codemap::Spanned {
-            node: LitKind::Int(i as u128, ast::LitIntType::Unsigned(UintTy::U32)),
-            span: *span
-        });
-
-        P(Expr {
-            id: ast::DUMMY_NODE_ID,
-            node: ExprKind::Lit(lv_lit),
-            span: *span,
-            attrs,
-        })
-    }
-
     fn expect_delimited_token_tree(&mut self) -> PResult<'a, (MacDelimiter, ThinTokenStream)> {
         let delim = match self.token {
             token::OpenDelim(delim) => delim,
@@ -2559,7 +2469,7 @@
     }
 
     /// Parse a block or unsafe block
-    pub fn parse_block_expr(&mut self, opt_label: Option<Label>,
+    fn parse_block_expr(&mut self, opt_label: Option<Label>,
                             lo: Span, blk_mode: BlockCheckMode,
                             outer_attrs: ThinVec<Attribute>)
                             -> PResult<'a, P<Expr>> {
@@ -2573,7 +2483,7 @@
     }
 
     /// parse a.b or a(13) or a[4] or just a
-    pub fn parse_dot_or_call_expr(&mut self,
+    fn parse_dot_or_call_expr(&mut self,
                                   already_parsed_attrs: Option<ThinVec<Attribute>>)
                                   -> PResult<'a, P<Expr>> {
         let attrs = self.parse_or_use_outer_attributes(already_parsed_attrs)?;
@@ -2583,7 +2493,7 @@
         self.parse_dot_or_call_expr_with(b, span, attrs)
     }
 
-    pub fn parse_dot_or_call_expr_with(&mut self,
+    fn parse_dot_or_call_expr_with(&mut self,
                                        e0: P<Expr>,
                                        lo: Span,
                                        mut attrs: ThinVec<Attribute>)
@@ -2737,7 +2647,7 @@
         return Ok(e);
     }
 
-    pub fn process_potential_macro_variable(&mut self) {
+    crate fn process_potential_macro_variable(&mut self) {
         let (token, span) = match self.token {
             token::Dollar if self.span.ctxt() != syntax_pos::hygiene::SyntaxContext::empty() &&
                              self.look_ahead(1, |t| t.is_ident()) => {
@@ -2768,7 +2678,7 @@
     }
 
     /// parse a single token tree from the input.
-    pub fn parse_token_tree(&mut self) -> TokenTree {
+    crate fn parse_token_tree(&mut self) -> TokenTree {
         match self.token {
             token::OpenDelim(..) => {
                 let frame = mem::replace(&mut self.token_cursor.frame,
@@ -2811,7 +2721,7 @@
     }
 
     /// Parse a prefix-unary-operator expr
-    pub fn parse_prefix_expr(&mut self,
+    fn parse_prefix_expr(&mut self,
                              already_parsed_attrs: Option<ThinVec<Attribute>>)
                              -> PResult<'a, P<Expr>> {
         let attrs = self.parse_or_use_outer_attributes(already_parsed_attrs)?;
@@ -2930,14 +2840,14 @@
     ///
     /// This parses an expression accounting for associativity and precedence of the operators in
     /// the expression.
-    pub fn parse_assoc_expr(&mut self,
+    fn parse_assoc_expr(&mut self,
                             already_parsed_attrs: Option<ThinVec<Attribute>>)
                             -> PResult<'a, P<Expr>> {
         self.parse_assoc_expr_with(0, already_parsed_attrs.into())
     }
 
     /// Parse an associative expression with operators of at least `min_prec` precedence
-    pub fn parse_assoc_expr_with(&mut self,
+    fn parse_assoc_expr_with(&mut self,
                                  min_prec: usize,
                                  lhs: LhsExpr)
                                  -> PResult<'a, P<Expr>> {
@@ -3266,7 +3176,7 @@
     }
 
     /// Parse an 'if' or 'if let' expression ('if' token already eaten)
-    pub fn parse_if_expr(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
+    fn parse_if_expr(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
         if self.check_keyword(keywords::Let) {
             return self.parse_if_let_expr(attrs);
         }
@@ -3302,7 +3212,7 @@
     }
 
     /// Parse an 'if let' expression ('if' token already eaten)
-    pub fn parse_if_let_expr(&mut self, attrs: ThinVec<Attribute>)
+    fn parse_if_let_expr(&mut self, attrs: ThinVec<Attribute>)
                              -> PResult<'a, P<Expr>> {
         let lo = self.prev_span;
         self.expect_keyword(keywords::Let)?;
@@ -3320,7 +3230,7 @@
     }
 
     // `move |args| expr`
-    pub fn parse_lambda_expr(&mut self,
+    fn parse_lambda_expr(&mut self,
                              attrs: ThinVec<Attribute>)
                              -> PResult<'a, P<Expr>>
     {
@@ -3357,7 +3267,7 @@
     }
 
     // `else` token already eaten
-    pub fn parse_else_expr(&mut self) -> PResult<'a, P<Expr>> {
+    fn parse_else_expr(&mut self) -> PResult<'a, P<Expr>> {
         if self.eat_keyword(keywords::If) {
             return self.parse_if_expr(ThinVec::new());
         } else {
@@ -3367,7 +3277,7 @@
     }
 
     /// Parse a 'for' .. 'in' expression ('for' token already eaten)
-    pub fn parse_for_expr(&mut self, opt_label: Option<Label>,
+    fn parse_for_expr(&mut self, opt_label: Option<Label>,
                           span_lo: Span,
                           mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
         // Parse: `for <src_pat> in <src_expr> <src_loop_block>`
@@ -3393,7 +3303,7 @@
     }
 
     /// Parse a 'while' or 'while let' expression ('while' token already eaten)
-    pub fn parse_while_expr(&mut self, opt_label: Option<Label>,
+    fn parse_while_expr(&mut self, opt_label: Option<Label>,
                             span_lo: Span,
                             mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
         if self.token.is_keyword(keywords::Let) {
@@ -3407,7 +3317,7 @@
     }
 
     /// Parse a 'while let' expression ('while' token already eaten)
-    pub fn parse_while_let_expr(&mut self, opt_label: Option<Label>,
+    fn parse_while_let_expr(&mut self, opt_label: Option<Label>,
                                 span_lo: Span,
                                 mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
         self.expect_keyword(keywords::Let)?;
@@ -3421,7 +3331,7 @@
     }
 
     // parse `loop {...}`, `loop` token already eaten
-    pub fn parse_loop_expr(&mut self, opt_label: Option<Label>,
+    fn parse_loop_expr(&mut self, opt_label: Option<Label>,
                            span_lo: Span,
                            mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
         let (iattrs, body) = self.parse_inner_attrs_and_block()?;
@@ -3431,7 +3341,7 @@
     }
 
     /// Parse a `do catch {...}` expression (`do catch` token already eaten)
-    pub fn parse_catch_expr(&mut self, span_lo: Span, mut attrs: ThinVec<Attribute>)
+    fn parse_catch_expr(&mut self, span_lo: Span, mut attrs: ThinVec<Attribute>)
         -> PResult<'a, P<Expr>>
     {
         let (iattrs, body) = self.parse_inner_attrs_and_block()?;
@@ -3479,7 +3389,7 @@
         return Ok(self.mk_expr(lo.to(hi), ExprKind::Match(discriminant, arms), attrs));
     }
 
-    pub fn parse_arm(&mut self) -> PResult<'a, Arm> {
+    crate fn parse_arm(&mut self) -> PResult<'a, Arm> {
         maybe_whole!(self, NtArm, |x| x);
 
         let attrs = self.parse_outer_attributes()?;
@@ -3558,7 +3468,7 @@
     /// Evaluate the closure with restrictions in place.
     ///
     /// After the closure is evaluated, restrictions are reset.
-    pub fn with_res<F, T>(&mut self, r: Restrictions, f: F) -> T
+    fn with_res<F, T>(&mut self, r: Restrictions, f: F) -> T
         where F: FnOnce(&mut Self) -> T
     {
         let old = self.restrictions;
@@ -3570,7 +3480,7 @@
     }
 
     /// Parse an expression, subject to the given restrictions
-    pub fn parse_expr_res(&mut self, r: Restrictions,
+    fn parse_expr_res(&mut self, r: Restrictions,
                           already_parsed_attrs: Option<ThinVec<Attribute>>)
                           -> PResult<'a, P<Expr>> {
         self.with_res(r, |this| this.parse_assoc_expr(already_parsed_attrs))
@@ -3710,26 +3620,89 @@
         Ok((before, slice, after))
     }
 
+    fn parse_pat_field(
+        &mut self,
+        lo: Span,
+        attrs: Vec<Attribute>
+    ) -> PResult<'a, codemap::Spanned<ast::FieldPat>> {
+        // Check if a colon exists one ahead. This means we're parsing a fieldname.
+        let hi;
+        let (subpat, fieldname, is_shorthand) = if self.look_ahead(1, |t| t == &token::Colon) {
+            // Parsing a pattern of the form "fieldname: pat"
+            let fieldname = self.parse_field_name()?;
+            self.bump();
+            let pat = self.parse_pat()?;
+            hi = pat.span;
+            (pat, fieldname, false)
+        } else {
+            // Parsing a pattern of the form "(box) (ref) (mut) fieldname"
+            let is_box = self.eat_keyword(keywords::Box);
+            let boxed_span = self.span;
+            let is_ref = self.eat_keyword(keywords::Ref);
+            let is_mut = self.eat_keyword(keywords::Mut);
+            let fieldname = self.parse_ident()?;
+            hi = self.prev_span;
+
+            let bind_type = match (is_ref, is_mut) {
+                (true, true) => BindingMode::ByRef(Mutability::Mutable),
+                (true, false) => BindingMode::ByRef(Mutability::Immutable),
+                (false, true) => BindingMode::ByValue(Mutability::Mutable),
+                (false, false) => BindingMode::ByValue(Mutability::Immutable),
+            };
+            let fieldpat = P(Pat {
+                id: ast::DUMMY_NODE_ID,
+                node: PatKind::Ident(bind_type, fieldname, None),
+                span: boxed_span.to(hi),
+            });
+
+            let subpat = if is_box {
+                P(Pat {
+                    id: ast::DUMMY_NODE_ID,
+                    node: PatKind::Box(fieldpat),
+                    span: lo.to(hi),
+                })
+            } else {
+                fieldpat
+            };
+            (subpat, fieldname, true)
+        };
+
+        Ok(codemap::Spanned {
+            span: lo.to(hi),
+            node: ast::FieldPat {
+                ident: fieldname,
+                pat: subpat,
+                is_shorthand,
+                attrs: attrs.into(),
+           }
+        })
+    }
+
     /// Parse the fields of a struct-like pattern
     fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<codemap::Spanned<ast::FieldPat>>, bool)> {
         let mut fields = Vec::new();
         let mut etc = false;
-        let mut first = true;
-        while self.token != token::CloseDelim(token::Brace) {
-            if first {
-                first = false;
-            } else {
-                self.expect(&token::Comma)?;
-                // accept trailing commas
-                if self.check(&token::CloseDelim(token::Brace)) { break }
-            }
+        let mut ate_comma = true;
+        let mut delayed_err: Option<DiagnosticBuilder<'a>> = None;
+        let mut etc_span = None;
 
+        while self.token != token::CloseDelim(token::Brace) {
             let attrs = self.parse_outer_attributes()?;
             let lo = self.span;
-            let hi;
+
+            // check that a comma comes after every field
+            if !ate_comma {
+                let err = self.struct_span_err(self.prev_span, "expected `,`");
+                return Err(err);
+            }
+            ate_comma = false;
 
             if self.check(&token::DotDot) || self.token == token::DotDotDot {
+                etc = true;
+                let mut etc_sp = self.span;
+
                 if self.token == token::DotDotDot { // Issue #46718
+                    // Accept `...` as if it were `..` to avoid further errors
                     let mut err = self.struct_span_err(self.span,
                                                        "expected field pattern, found `...`");
                     err.span_suggestion_with_applicability(
@@ -3740,73 +3713,76 @@
                     );
                     err.emit();
                 }
+                self.bump();  // `..` || `...`:w
 
-                self.bump();
-                if self.token != token::CloseDelim(token::Brace) {
-                    let token_str = self.this_token_to_string();
-                    let mut err = self.fatal(&format!("expected `{}`, found `{}`", "}", token_str));
-                    if self.token == token::Comma { // Issue #49257
-                        err.span_label(self.span,
-                                       "`..` must be in the last position, \
-                                        and cannot have a trailing comma");
+                if self.token == token::CloseDelim(token::Brace) {
+                    etc_span = Some(etc_sp);
+                    break;
+                }
+                let token_str = self.this_token_to_string();
+                let mut err = self.fatal(&format!("expected `}}`, found `{}`", token_str));
+
+                err.span_label(self.span, "expected `}`");
+                let mut comma_sp = None;
+                if self.token == token::Comma { // Issue #49257
+                    etc_sp = etc_sp.to(self.sess.codemap().span_until_non_whitespace(self.span));
+                    err.span_label(etc_sp,
+                                   "`..` must be at the end and cannot have a trailing comma");
+                    comma_sp = Some(self.span);
+                    self.bump();
+                    ate_comma = true;
+                }
+
+                etc_span = Some(etc_sp);
+                if self.token == token::CloseDelim(token::Brace) {
+                    // If the struct looks otherwise well formed, recover and continue.
+                    if let Some(sp) = comma_sp {
+                        err.span_suggestion_short(sp, "remove this comma", "".into());
+                    }
+                    err.emit();
+                    break;
+                } else if self.token.is_ident() && ate_comma {
+                    // Accept fields coming after `..,`.
+                    // This way we avoid "pattern missing fields" errors afterwards.
+                    // We delay this error until the end in order to have a span for a
+                    // suggested fix.
+                    if let Some(mut delayed_err) = delayed_err {
+                        delayed_err.emit();
+                        return Err(err);
                     } else {
-                        err.span_label(self.span, "expected `}`");
+                        delayed_err = Some(err);
+                    }
+                } else {
+                    if let Some(mut err) = delayed_err {
+                        err.emit();
                     }
                     return Err(err);
                 }
-                etc = true;
-                break;
             }
 
-            // Check if a colon exists one ahead. This means we're parsing a fieldname.
-            let (subpat, fieldname, is_shorthand) = if self.look_ahead(1, |t| t == &token::Colon) {
-                // Parsing a pattern of the form "fieldname: pat"
-                let fieldname = self.parse_field_name()?;
-                self.bump();
-                let pat = self.parse_pat()?;
-                hi = pat.span;
-                (pat, fieldname, false)
-            } else {
-                // Parsing a pattern of the form "(box) (ref) (mut) fieldname"
-                let is_box = self.eat_keyword(keywords::Box);
-                let boxed_span = self.span;
-                let is_ref = self.eat_keyword(keywords::Ref);
-                let is_mut = self.eat_keyword(keywords::Mut);
-                let fieldname = self.parse_ident()?;
-                hi = self.prev_span;
-
-                let bind_type = match (is_ref, is_mut) {
-                    (true, true) => BindingMode::ByRef(Mutability::Mutable),
-                    (true, false) => BindingMode::ByRef(Mutability::Immutable),
-                    (false, true) => BindingMode::ByValue(Mutability::Mutable),
-                    (false, false) => BindingMode::ByValue(Mutability::Immutable),
-                };
-                let fieldpat = P(Pat {
-                    id: ast::DUMMY_NODE_ID,
-                    node: PatKind::Ident(bind_type, fieldname, None),
-                    span: boxed_span.to(hi),
-                });
-
-                let subpat = if is_box {
-                    P(Pat {
-                        id: ast::DUMMY_NODE_ID,
-                        node: PatKind::Box(fieldpat),
-                        span: lo.to(hi),
-                    })
-                } else {
-                    fieldpat
-                };
-                (subpat, fieldname, true)
-            };
-
-            fields.push(codemap::Spanned { span: lo.to(hi),
-                                           node: ast::FieldPat {
-                                               ident: fieldname,
-                                               pat: subpat,
-                                               is_shorthand,
-                                               attrs: attrs.into(),
-                                           }
+            fields.push(match self.parse_pat_field(lo, attrs) {
+                Ok(field) => field,
+                Err(err) => {
+                    if let Some(mut delayed_err) = delayed_err {
+                        delayed_err.emit();
+                    }
+                    return Err(err);
+                }
             });
+            ate_comma = self.eat(&token::Comma);
+        }
+
+        if let Some(mut err) = delayed_err {
+            if let Some(etc_span) = etc_span {
+                err.multipart_suggestion(
+                    "move the `..` to the end of the field list",
+                    vec![
+                        (etc_span, "".into()),
+                        (self.span, format!("{}.. }}", if ate_comma { "" } else { ", " })),
+                    ],
+                );
+            }
+            err.emit();
         }
         return Ok((fields, etc));
     }
@@ -3848,7 +3824,7 @@
     /// A wrapper around `parse_pat` with some special error handling for the
     /// "top-level" patterns in a match arm, `for` loop, `let`, &c. (in contast
     /// to subpatterns within such).
-    pub fn parse_top_level_pat(&mut self) -> PResult<'a, P<Pat>> {
+    fn parse_top_level_pat(&mut self) -> PResult<'a, P<Pat>> {
         let pat = self.parse_pat()?;
         if self.token == token::Comma {
             // An unexpected comma after a top-level pattern is a clue that the
@@ -4697,7 +4673,7 @@
     }
 
     /// Parse a statement, including the trailing semicolon.
-    pub fn parse_full_stmt(&mut self, macro_legacy_warnings: bool) -> PResult<'a, Option<Stmt>> {
+    crate fn parse_full_stmt(&mut self, macro_legacy_warnings: bool) -> PResult<'a, Option<Stmt>> {
         // skip looking for a trailing semicolon when we have an interpolated statement
         maybe_whole!(self, NtStmt, |x| Some(x));
 
@@ -4770,6 +4746,7 @@
                                  self.check_keyword(keywords::For) ||
                                  self.check(&token::OpenDelim(token::Paren));
             if is_bound_start {
+                let lo = self.span;
                 let has_parens = self.eat(&token::OpenDelim(token::Paren));
                 let question = if self.eat(&token::Question) { Some(self.prev_span) } else { None };
                 if self.token.is_lifetime() {
@@ -4778,10 +4755,17 @@
                                       "`?` may only modify trait bounds, not lifetime bounds");
                     }
                     bounds.push(RegionTyParamBound(self.expect_lifetime()));
+                    if has_parens {
+                        self.expect(&token::CloseDelim(token::Paren))?;
+                        self.span_err(self.prev_span,
+                                      "parenthesized lifetime bounds are not supported");
+                    }
                 } else {
-                    let lo = self.span;
                     let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
                     let path = self.parse_path(PathStyle::Type)?;
+                    if has_parens {
+                        self.expect(&token::CloseDelim(token::Paren))?;
+                    }
                     let poly_trait = PolyTraitRef::new(lifetime_defs, path, lo.to(self.prev_span));
                     let modifier = if question.is_some() {
                         TraitBoundModifier::Maybe
@@ -4790,18 +4774,11 @@
                     };
                     bounds.push(TraitTyParamBound(poly_trait, modifier));
                 }
-                if has_parens {
-                    self.expect(&token::CloseDelim(token::Paren))?;
-                    if let Some(&RegionTyParamBound(..)) = bounds.last() {
-                        self.span_err(self.prev_span,
-                                      "parenthesized lifetime bounds are not supported");
-                    }
-                }
             } else {
                 break
             }
 
-            if !allow_plus || !self.eat(&token::BinOp(token::Plus)) {
+            if !allow_plus || !self.eat_plus() {
                 break
             }
         }
@@ -4820,7 +4797,7 @@
         while self.check_lifetime() {
             lifetimes.push(self.expect_lifetime());
 
-            if !self.eat(&token::BinOp(token::Plus)) {
+            if !self.eat_plus() {
                 break
             }
         }
@@ -4886,7 +4863,7 @@
 
     /// Parses (possibly empty) list of lifetime and type parameters, possibly including
     /// trailing comma and erroneous trailing attributes.
-    pub fn parse_generic_params(&mut self) -> PResult<'a, Vec<ast::GenericParam>> {
+    crate fn parse_generic_params(&mut self) -> PResult<'a, Vec<ast::GenericParam>> {
         let mut params = Vec::new();
         let mut seen_ty_param = false;
         loop {
@@ -4936,7 +4913,7 @@
     /// matches generics = ( ) | ( < > ) | ( < typaramseq ( , )? > ) | ( < lifetimes ( , )? > )
     ///                  | ( < lifetimes , typaramseq ( , )? > )
     /// where   typaramseq = ( typaram ) | ( typaram , typaramseq )
-    pub fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
+    fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
         maybe_whole!(self, NtGenerics, |x| x);
 
         let span_lo = self.span;
@@ -4966,7 +4943,7 @@
         let mut seen_type = false;
         let mut seen_binding = false;
         loop {
-            if self.check_lifetime() && self.look_ahead(1, |t| t != &token::BinOp(token::Plus)) {
+            if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
                 // Parse lifetime argument.
                 lifetimes.push(self.expect_lifetime());
                 if seen_type || seen_binding {
@@ -5010,7 +4987,7 @@
     /// ```ignore (only-for-syntax-highlight)
     /// where T : Trait<U, V> + 'b, 'a : 'b
     /// ```
-    pub fn parse_where_clause(&mut self) -> PResult<'a, WhereClause> {
+    fn parse_where_clause(&mut self) -> PResult<'a, WhereClause> {
         maybe_whole!(self, NtWhereClause, |x| x);
 
         let mut where_clause = WhereClause {
@@ -5035,7 +5012,7 @@
 
         loop {
             let lo = self.span;
-            if self.check_lifetime() && self.look_ahead(1, |t| t != &token::BinOp(token::Plus)) {
+            if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
                 let lifetime = self.expect_lifetime();
                 // Bounds starting with a colon are mandatory, but possibly empty.
                 self.expect(&token::Colon)?;
@@ -5161,7 +5138,7 @@
     }
 
     /// Parse the argument list and result type of a function declaration
-    pub fn parse_fn_decl(&mut self, allow_variadic: bool) -> PResult<'a, P<FnDecl>> {
+    fn parse_fn_decl(&mut self, allow_variadic: bool) -> PResult<'a, P<FnDecl>> {
 
         let (args, variadic) = self.parse_fn_args(true, allow_variadic)?;
         let ret_ty = self.parse_ret_ty(true)?;
@@ -5190,36 +5167,36 @@
         // Only a limited set of initial token sequences is considered self parameters, anything
         // else is parsed as a normal function parameter list, so some lookahead is required.
         let eself_lo = self.span;
-        let (eself, eself_ident) = match self.token {
+        let (eself, eself_ident, eself_hi) = match self.token {
             token::BinOp(token::And) => {
                 // &self
                 // &mut self
                 // &'lt self
                 // &'lt mut self
                 // &not_self
-                if isolated_self(self, 1) {
+                (if isolated_self(self, 1) {
                     self.bump();
-                    (SelfKind::Region(None, Mutability::Immutable), expect_ident(self))
+                    SelfKind::Region(None, Mutability::Immutable)
                 } else if self.look_ahead(1, |t| t.is_keyword(keywords::Mut)) &&
                           isolated_self(self, 2) {
                     self.bump();
                     self.bump();
-                    (SelfKind::Region(None, Mutability::Mutable), expect_ident(self))
+                    SelfKind::Region(None, Mutability::Mutable)
                 } else if self.look_ahead(1, |t| t.is_lifetime()) &&
                           isolated_self(self, 2) {
                     self.bump();
                     let lt = self.expect_lifetime();
-                    (SelfKind::Region(Some(lt), Mutability::Immutable), expect_ident(self))
+                    SelfKind::Region(Some(lt), Mutability::Immutable)
                 } else if self.look_ahead(1, |t| t.is_lifetime()) &&
                           self.look_ahead(2, |t| t.is_keyword(keywords::Mut)) &&
                           isolated_self(self, 3) {
                     self.bump();
                     let lt = self.expect_lifetime();
                     self.bump();
-                    (SelfKind::Region(Some(lt), Mutability::Mutable), expect_ident(self))
+                    SelfKind::Region(Some(lt), Mutability::Mutable)
                 } else {
                     return Ok(None);
-                }
+                }, expect_ident(self), self.prev_span)
             }
             token::BinOp(token::Star) => {
                 // *self
@@ -5227,43 +5204,45 @@
                 // *mut self
                 // *not_self
                 // Emit special error for `self` cases.
-                if isolated_self(self, 1) {
+                (if isolated_self(self, 1) {
                     self.bump();
                     self.span_err(self.span, "cannot pass `self` by raw pointer");
-                    (SelfKind::Value(Mutability::Immutable), expect_ident(self))
+                    SelfKind::Value(Mutability::Immutable)
                 } else if self.look_ahead(1, |t| t.is_mutability()) &&
                           isolated_self(self, 2) {
                     self.bump();
                     self.bump();
                     self.span_err(self.span, "cannot pass `self` by raw pointer");
-                    (SelfKind::Value(Mutability::Immutable), expect_ident(self))
+                    SelfKind::Value(Mutability::Immutable)
                 } else {
                     return Ok(None);
-                }
+                }, expect_ident(self), self.prev_span)
             }
             token::Ident(..) => {
                 if isolated_self(self, 0) {
                     // self
                     // self: TYPE
                     let eself_ident = expect_ident(self);
-                    if self.eat(&token::Colon) {
+                    let eself_hi = self.prev_span;
+                    (if self.eat(&token::Colon) {
                         let ty = self.parse_ty()?;
-                        (SelfKind::Explicit(ty, Mutability::Immutable), eself_ident)
+                        SelfKind::Explicit(ty, Mutability::Immutable)
                     } else {
-                        (SelfKind::Value(Mutability::Immutable), eself_ident)
-                    }
+                        SelfKind::Value(Mutability::Immutable)
+                    }, eself_ident, eself_hi)
                 } else if self.token.is_keyword(keywords::Mut) &&
                           isolated_self(self, 1) {
                     // mut self
                     // mut self: TYPE
                     self.bump();
                     let eself_ident = expect_ident(self);
-                    if self.eat(&token::Colon) {
+                    let eself_hi = self.prev_span;
+                    (if self.eat(&token::Colon) {
                         let ty = self.parse_ty()?;
-                        (SelfKind::Explicit(ty, Mutability::Mutable), eself_ident)
+                        SelfKind::Explicit(ty, Mutability::Mutable)
                     } else {
-                        (SelfKind::Value(Mutability::Mutable), eself_ident)
-                    }
+                        SelfKind::Value(Mutability::Mutable)
+                    }, eself_ident, eself_hi)
                 } else {
                     return Ok(None);
                 }
@@ -5271,7 +5250,7 @@
             _ => return Ok(None),
         };
 
-        let eself = codemap::respan(eself_lo.to(self.prev_span), eself);
+        let eself = codemap::respan(eself_lo.to(eself_hi), eself);
         Ok(Some(Arg::from_self(eself, eself_ident)))
     }
 
@@ -5371,7 +5350,7 @@
     }
 
     /// true if we are looking at `const ID`, false for things like `const fn` etc
-    pub fn is_const_item(&mut self) -> bool {
+    fn is_const_item(&mut self) -> bool {
         self.token.is_keyword(keywords::Const) &&
             !self.look_ahead(1, |t| t.is_keyword(keywords::Fn)) &&
             !self.look_ahead(1, |t| t.is_keyword(keywords::Unsafe))
@@ -5385,7 +5364,7 @@
     /// - `const unsafe fn`
     /// - `extern fn`
     /// - etc
-    pub fn parse_fn_front_matter(&mut self) -> PResult<'a, (Spanned<Constness>, Unsafety, Abi)> {
+    fn parse_fn_front_matter(&mut self) -> PResult<'a, (Spanned<Constness>, Unsafety, Abi)> {
         let is_const_fn = self.eat_keyword(keywords::Const);
         let const_span = self.prev_span;
         let unsafety = self.parse_unsafety();
@@ -5404,7 +5383,7 @@
     }
 
     /// Parse an impl item.
-    pub fn parse_impl_item(&mut self, at_end: &mut bool) -> PResult<'a, ImplItem> {
+    crate fn parse_impl_item(&mut self, at_end: &mut bool) -> PResult<'a, ImplItem> {
         maybe_whole!(self, NtImplItem, |x| x);
         let attrs = self.parse_outer_attributes()?;
         let (mut item, tokens) = self.collect_tokens(|this| {
@@ -5824,7 +5803,7 @@
         }
     }
 
-    pub fn parse_record_struct_body(&mut self) -> PResult<'a, Vec<StructField>> {
+    fn parse_record_struct_body(&mut self) -> PResult<'a, Vec<StructField>> {
         let mut fields = Vec::new();
         if self.eat(&token::OpenDelim(token::Brace)) {
             while self.token != token::CloseDelim(token::Brace) {
@@ -5851,7 +5830,7 @@
         Ok(fields)
     }
 
-    pub fn parse_tuple_struct_body(&mut self) -> PResult<'a, Vec<StructField>> {
+    fn parse_tuple_struct_body(&mut self) -> PResult<'a, Vec<StructField>> {
         // This is the case where we find `struct Foo<T>(T) where T: Copy;`
         // Unit like structs are handled in parse_item_struct function
         let fields = self.parse_unspanned_seq(
@@ -5877,7 +5856,7 @@
     }
 
     /// Parse a structure field declaration
-    pub fn parse_single_struct_field(&mut self,
+    fn parse_single_struct_field(&mut self,
                                      lo: Span,
                                      vis: Visibility,
                                      attrs: Vec<Attribute> )
@@ -6931,7 +6910,7 @@
     }
 
     /// Parse a foreign item.
-    pub fn parse_foreign_item(&mut self) -> PResult<'a, Option<ForeignItem>> {
+    crate fn parse_foreign_item(&mut self) -> PResult<'a, Option<ForeignItem>> {
         maybe_whole!(self, NtForeignItem, |ni| Some(ni));
 
         let attrs = self.parse_outer_attributes()?;
@@ -7190,7 +7169,7 @@
                     UseTreeKind::Nested(self.parse_use_tree_list()?)
                 }
             } else {
-                UseTreeKind::Simple(self.parse_rename()?)
+                UseTreeKind::Simple(self.parse_rename()?, ast::DUMMY_NODE_ID, ast::DUMMY_NODE_ID)
             }
         };
 
@@ -7233,7 +7212,7 @@
         })
     }
 
-    pub fn parse_optional_str(&mut self) -> Option<(Symbol, ast::StrStyle, Option<ast::Name>)> {
+    fn parse_optional_str(&mut self) -> Option<(Symbol, ast::StrStyle, Option<ast::Name>)> {
         let ret = match self.token {
             token::Literal(token::Str_(s), suf) => (s, ast::StrStyle::Cooked, suf),
             token::Literal(token::StrRaw(s, n), suf) => (s, ast::StrStyle::Raw(n), suf),
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 9770fbc..7ea047d 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -80,7 +80,7 @@
 }
 
 impl Lit {
-    pub fn short_name(&self) -> &'static str {
+    crate fn short_name(&self) -> &'static str {
         match *self {
             Byte(_) => "byte",
             Char(_) => "char",
@@ -217,16 +217,15 @@
         Ident(ident, ident.is_raw_guess())
     }
 
-    /// Returns `true` if the token starts with '>'.
-    pub fn is_like_gt(&self) -> bool {
+    crate fn is_like_plus(&self) -> bool {
         match *self {
-            BinOp(Shr) | BinOpEq(Shr) | Gt | Ge => true,
+            BinOp(Plus) | BinOpEq(Plus) => true,
             _ => false,
         }
     }
 
     /// Returns `true` if the token can appear at the start of an expression.
-    pub fn can_begin_expr(&self) -> bool {
+    crate fn can_begin_expr(&self) -> bool {
         match *self {
             Ident(ident, is_raw)              =>
                 ident_can_begin_expr(ident, is_raw), // value name or keyword
@@ -258,7 +257,7 @@
     }
 
     /// Returns `true` if the token can appear at the start of a type.
-    pub fn can_begin_type(&self) -> bool {
+    crate fn can_begin_type(&self) -> bool {
         match *self {
             Ident(ident, is_raw)        =>
                 ident_can_begin_type(ident, is_raw), // type name or keyword
@@ -281,13 +280,13 @@
     }
 
     /// Returns `true` if the token can appear at the start of a generic bound.
-    pub fn can_begin_bound(&self) -> bool {
+    crate fn can_begin_bound(&self) -> bool {
         self.is_path_start() || self.is_lifetime() || self.is_keyword(keywords::For) ||
         self == &Question || self == &OpenDelim(Paren)
     }
 
     /// Returns `true` if the token is any literal
-    pub fn is_lit(&self) -> bool {
+    crate fn is_lit(&self) -> bool {
         match *self {
             Literal(..) => true,
             _           => false,
@@ -296,7 +295,7 @@
 
     /// Returns `true` if the token is any literal, a minus (which can follow a literal,
     /// for example a '-42', or one of the boolean idents).
-    pub fn can_begin_literal_or_bool(&self) -> bool {
+    crate fn can_begin_literal_or_bool(&self) -> bool {
         match *self {
             Literal(..)  => true,
             BinOp(Minus) => true,
@@ -333,37 +332,21 @@
         self.ident().is_some()
     }
     /// Returns `true` if the token is a lifetime.
-    pub fn is_lifetime(&self) -> bool {
+    crate fn is_lifetime(&self) -> bool {
         self.lifetime().is_some()
     }
 
     /// Returns `true` if the token is a identifier whose name is the given
     /// string slice.
-    pub fn is_ident_named(&self, name: &str) -> bool {
+    crate fn is_ident_named(&self, name: &str) -> bool {
         match self.ident() {
             Some((ident, _)) => ident.as_str() == name,
             None => false
         }
     }
 
-    /// Returns `true` if the token is a documentation comment.
-    pub fn is_doc_comment(&self) -> bool {
-        match *self {
-            DocComment(..)   => true,
-            _                => false,
-        }
-    }
-
-    /// Returns `true` if the token is interpolated.
-    pub fn is_interpolated(&self) -> bool {
-        match *self {
-            Interpolated(..) => true,
-            _                => false,
-        }
-    }
-
     /// Returns `true` if the token is an interpolated path.
-    pub fn is_path(&self) -> bool {
+    fn is_path(&self) -> bool {
         if let Interpolated(ref nt) = *self {
             if let NtPath(..) = nt.0 {
                 return true;
@@ -373,16 +356,16 @@
     }
 
     /// Returns `true` if the token is either the `mut` or `const` keyword.
-    pub fn is_mutability(&self) -> bool {
+    crate fn is_mutability(&self) -> bool {
         self.is_keyword(keywords::Mut) ||
         self.is_keyword(keywords::Const)
     }
 
-    pub fn is_qpath_start(&self) -> bool {
+    crate fn is_qpath_start(&self) -> bool {
         self == &Lt || self == &BinOp(Shl)
     }
 
-    pub fn is_path_start(&self) -> bool {
+    crate fn is_path_start(&self) -> bool {
         self == &ModSep || self.is_qpath_start() || self.is_path() ||
         self.is_path_segment_keyword() || self.is_ident() && !self.is_reserved_ident()
     }
@@ -409,7 +392,7 @@
     }
 
     /// Returns `true` if the token is a keyword used in the language.
-    pub fn is_used_keyword(&self) -> bool {
+    crate fn is_used_keyword(&self) -> bool {
         match self.ident() {
             Some((id, false)) => id.is_used_keyword(),
             _ => false,
@@ -417,7 +400,7 @@
     }
 
     /// Returns `true` if the token is a keyword reserved for possible future use.
-    pub fn is_unused_keyword(&self) -> bool {
+    crate fn is_unused_keyword(&self) -> bool {
         match self.ident() {
             Some((id, false)) => id.is_unused_keyword(),
             _ => false,
@@ -432,7 +415,7 @@
         }
     }
 
-    pub fn glue(self, joint: Token) -> Option<Token> {
+    crate fn glue(self, joint: Token) -> Option<Token> {
         Some(match self {
             Eq => match joint {
                 Eq => EqEq,
@@ -500,7 +483,7 @@
 
     /// Returns tokens that are likely to be typed accidentally instead of the current token.
     /// Enables better error recovery when the wrong token is found.
-    pub fn similar_tokens(&self) -> Option<Vec<Token>> {
+    crate fn similar_tokens(&self) -> Option<Vec<Token>> {
         match *self {
             Comma => Some(vec![Dot, Lt]),
             Semi => Some(vec![Colon]),
@@ -596,7 +579,7 @@
 
     // See comments in `interpolated_to_tokenstream` for why we care about
     // *probably* equal here rather than actual equality
-    pub fn probably_equal_for_proc_macro(&self, other: &Token) -> bool {
+    crate fn probably_equal_for_proc_macro(&self, other: &Token) -> bool {
         if mem::discriminant(self) != mem::discriminant(other) {
             return false
         }
@@ -725,7 +708,7 @@
     }
 }
 
-pub fn is_op(tok: &Token) -> bool {
+crate fn is_op(tok: &Token) -> bool {
     match *tok {
         OpenDelim(..) | CloseDelim(..) | Literal(..) | DocComment(..) |
         Ident(..) | Lifetime(..) | Interpolated(..) |
@@ -751,11 +734,11 @@
 }
 
 impl LazyTokenStream {
-    pub fn new() -> Self {
+    fn new() -> Self {
         LazyTokenStream(Lock::new(None))
     }
 
-    pub fn force<F: FnOnce() -> TokenStream>(&self, f: F) -> TokenStream {
+    fn force<F: FnOnce() -> TokenStream>(&self, f: F) -> TokenStream {
         let mut opt_stream = self.0.lock();
         if opt_stream.is_none() {
             *opt_stream = Some(f());
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 10b7286..87edfd6 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -2958,7 +2958,7 @@
 
     pub fn print_use_tree(&mut self, tree: &ast::UseTree) -> io::Result<()> {
         match tree.kind {
-            ast::UseTreeKind::Simple(rename) => {
+            ast::UseTreeKind::Simple(rename, ..) => {
                 self.print_path(&tree.prefix, false, 0)?;
                 if let Some(rename) = rename {
                     self.s.space()?;
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs
index e63a3d4..da7deb3 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -335,7 +335,7 @@
 fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool {
     let has_test_attr = attr::contains_name(&i.attrs, "test");
 
-    fn has_test_signature(cx: &TestCtxt, i: &ast::Item) -> HasTestSignature {
+    fn has_test_signature(_cx: &TestCtxt, i: &ast::Item) -> HasTestSignature {
         let has_should_panic_attr = attr::contains_name(&i.attrs, "should_panic");
         match i.node {
             ast::ItemKind::Fn(ref decl, _, _, _, ref generics, _) => {
@@ -351,15 +351,14 @@
                     return No(BadTestSignature::NoArgumentsAllowed);
                 }
 
-                match (has_output, cx.features.termination_trait_test, has_should_panic_attr) {
-                    (true, true, true) => No(BadTestSignature::ShouldPanicOnlyWithNoArgs),
-                    (true, true, false) => if generics.is_parameterized() {
+                match (has_output, has_should_panic_attr) {
+                    (true, true) => No(BadTestSignature::ShouldPanicOnlyWithNoArgs),
+                    (true, false) => if generics.is_parameterized() {
                         No(BadTestSignature::WrongTypeSignature)
                     } else {
                         Yes
                     },
-                    (true, false, _) => No(BadTestSignature::WrongTypeSignature),
-                    (false, _, _) => Yes
+                    (false, _) => Yes
                 }
             }
             _ => No(BadTestSignature::NotEvenAFunction),
@@ -395,31 +394,12 @@
 fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool {
     let has_bench_attr = attr::contains_name(&i.attrs, "bench");
 
-    fn has_bench_signature(cx: &TestCtxt, i: &ast::Item) -> bool {
+    fn has_bench_signature(_cx: &TestCtxt, i: &ast::Item) -> bool {
         match i.node {
-            ast::ItemKind::Fn(ref decl, _, _, _, ref generics, _) => {
-                let input_cnt = decl.inputs.len();
-
-                // If the termination trait is active, the compiler will check that the output
-                // type implements the `Termination` trait as `libtest` enforces that.
-                let output_matches = if cx.features.termination_trait_test {
-                    true
-                } else {
-                    let no_output = match decl.output {
-                        ast::FunctionRetTy::Default(..) => true,
-                        ast::FunctionRetTy::Ty(ref t) if t.node == ast::TyKind::Tup(vec![]) => true,
-                        _ => false
-                    };
-                    let tparm_cnt = generics.params.iter()
-                        .filter(|param| param.is_type_param())
-                        .count();
-
-                    no_output && tparm_cnt == 0
-                };
-
+            ast::ItemKind::Fn(ref decl, _, _, _, _, _) => {
                 // NB: inadequate check, but we're running
                 // well before resolve, can't get too deep.
-                input_cnt == 1 && output_matches
+                decl.inputs.len() == 1
             }
             _ => false
         }
@@ -430,13 +410,8 @@
     if has_bench_attr && !has_bench_signature {
         let diag = cx.span_diagnostic;
 
-        if cx.features.termination_trait_test {
-            diag.span_err(i.span, "functions used as benches must have signature \
+        diag.span_err(i.span, "functions used as benches must have signature \
                                    `fn(&mut Bencher) -> impl Termination`");
-        } else {
-            diag.span_err(i.span, "functions used as benches must have signature \
-                                   `fn(&mut Bencher) -> ()`");
-        }
     }
 
     has_bench_attr && has_bench_signature
@@ -517,7 +492,7 @@
         (ast::ItemKind::Use(P(ast::UseTree {
             span: DUMMY_SP,
             prefix: path_node(vec![id_test]),
-            kind: ast::UseTreeKind::Simple(None),
+            kind: ast::UseTreeKind::Simple(None, ast::DUMMY_NODE_ID, ast::DUMMY_NODE_ID),
         })),
          ast::VisibilityKind::Public, keywords::Invalid.ident())
     } else {
@@ -613,7 +588,7 @@
         let use_path = ast::UseTree {
             span: DUMMY_SP,
             prefix: path_node(vec![mod_ident, Ident::from_str("main")]),
-            kind: ast::UseTreeKind::Simple(Some(rename)),
+            kind: ast::UseTreeKind::Simple(Some(rename), ast::DUMMY_NODE_ID, ast::DUMMY_NODE_ID),
         };
 
         expander.fold_item(P(ast::Item {
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index dca0e2f..adda39c 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -356,7 +356,8 @@
 ) {
     visitor.visit_path(&use_tree.prefix, id);
     match use_tree.kind {
-        UseTreeKind::Simple(rename) => {
+        UseTreeKind::Simple(rename, ..) => {
+            // the extra IDs are handled during HIR lowering
             if let Some(rename) = rename {
                 visitor.visit_ident(rename);
             }
diff --git a/src/libsyntax_pos/edition.rs b/src/libsyntax_pos/edition.rs
index 18446c1..67cd936 100644
--- a/src/libsyntax_pos/edition.rs
+++ b/src/libsyntax_pos/edition.rs
@@ -15,7 +15,7 @@
 #[derive(Clone, Copy, Hash, PartialOrd, Ord, Eq, PartialEq, Debug, RustcEncodable, RustcDecodable)]
 #[non_exhaustive]
 pub enum Edition {
-    // editions must be kept in order, newest to oldest
+    // editions must be kept in order, oldest to newest
 
     /// The 2015 edition
     Edition2015,
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index 1365ac3..6dd910f 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -489,6 +489,10 @@
     DotFill,
     QuestionMark,
     Catch,
+    /// Desugaring of an `impl Trait` in return type position
+    /// to an `existential type Foo: Trait;` + replacing the
+    /// `impl Trait` with `Foo`.
+    ExistentialReturnType,
 }
 
 impl CompilerDesugaringKind {
@@ -498,6 +502,7 @@
             DotFill => "...",
             QuestionMark => "?",
             Catch => "do catch",
+            ExistentialReturnType => "existental type",
         };
         Symbol::intern(s)
     }
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index a4b2d9d..abe738d 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -311,6 +311,17 @@
                 ident: Ident::with_empty_ctxt(super::Symbol($index))
             };
         )*
+
+        impl ::std::str::FromStr for Keyword {
+            type Err = ();
+
+            fn from_str(s: &str) -> Result<Self, ()> {
+                match s {
+                    $($string => Ok($konst),)*
+                    _ => Err(()),
+                }
+            }
+        }
     }
 
     impl Interner {
@@ -373,34 +384,30 @@
 
     // Keywords reserved for future use.
     (40, Abstract,           "abstract")
-    (41, Alignof,            "alignof")
-    (42, Become,             "become")
-    (43, Do,                 "do")
-    (44, Final,              "final")
-    (45, Macro,              "macro")
-    (46, Offsetof,           "offsetof")
-    (47, Override,           "override")
-    (48, Priv,               "priv")
-    (49, Pure,               "pure")
-    (50, Sizeof,             "sizeof")
-    (51, Typeof,             "typeof")
-    (52, Unsized,            "unsized")
-    (53, Virtual,            "virtual")
-    (54, Yield,              "yield")
+    (41, Become,             "become")
+    (42, Do,                 "do")
+    (43, Final,              "final")
+    (44, Macro,              "macro")
+    (45, Override,           "override")
+    (46, Priv,               "priv")
+    (47, Typeof,             "typeof")
+    (48, Unsized,            "unsized")
+    (49, Virtual,            "virtual")
+    (50, Yield,              "yield")
 
     // Edition-specific keywords reserved for future use.
-    (55, Async,              "async") // >= 2018 Edition Only
+    (51, Async,              "async") // >= 2018 Edition Only
 
     // Special lifetime names
-    (56, UnderscoreLifetime, "'_")
-    (57, StaticLifetime,     "'static")
+    (52, UnderscoreLifetime, "'_")
+    (53, StaticLifetime,     "'static")
 
     // Weak keywords, have special meaning only in specific contexts.
-    (58, Auto,               "auto")
-    (59, Catch,              "catch")
-    (60, Default,            "default")
-    (61, Dyn,                "dyn")
-    (62, Union,              "union")
+    (54, Auto,               "auto")
+    (55, Catch,              "catch")
+    (56, Default,            "default")
+    (57, Dyn,                "dyn")
+    (58, Union,              "union")
 }
 
 impl Symbol {
diff --git a/src/test/codegen/abi-main-signature-16bit-c-int.rs b/src/test/codegen/abi-main-signature-16bit-c-int.rs
index 367d509..df5cba1 100644
--- a/src/test/codegen/abi-main-signature-16bit-c-int.rs
+++ b/src/test/codegen/abi-main-signature-16bit-c-int.rs
@@ -22,6 +22,7 @@
 // ignore-powerpc64
 // ignore-s390x
 // ignore-sparc
+// ignore-sparc64
 // ignore-wasm32
 // ignore-x86
 // ignore-x86_64
diff --git a/src/test/codegen/fastcall-inreg.rs b/src/test/codegen/fastcall-inreg.rs
index d6dd3f3..77e3781 100644
--- a/src/test/codegen/fastcall-inreg.rs
+++ b/src/test/codegen/fastcall-inreg.rs
@@ -29,6 +29,7 @@
 // ignore-r600
 // ignore-amdgcn
 // ignore-sparc
+// ignore-sparc64
 // ignore-sparcv9
 // ignore-sparcel
 // ignore-s390x
diff --git a/src/test/codegen/repr-transparent-aggregates-1.rs b/src/test/codegen/repr-transparent-aggregates-1.rs
index 2eeed2b..a1185cc 100644
--- a/src/test/codegen/repr-transparent-aggregates-1.rs
+++ b/src/test/codegen/repr-transparent-aggregates-1.rs
@@ -18,7 +18,6 @@
 // See repr-transparent.rs
 
 #![crate_type="lib"]
-#![feature(repr_transparent)]
 
 
 #[repr(C)]
diff --git a/src/test/codegen/repr-transparent-aggregates-2.rs b/src/test/codegen/repr-transparent-aggregates-2.rs
index 9605ded..b4623eb 100644
--- a/src/test/codegen/repr-transparent-aggregates-2.rs
+++ b/src/test/codegen/repr-transparent-aggregates-2.rs
@@ -13,14 +13,18 @@
 // ignore-aarch64
 // ignore-asmjs
 // ignore-mips64
+// ignore-powerpc
+// ignore-powerpc64
+// ignore-powerpc64le
 // ignore-s390x
+// ignore-sparc
+// ignore-sparc64
 // ignore-wasm
 // ignore-x86
 // ignore-x86_64
 // See repr-transparent.rs
 
 #![crate_type="lib"]
-#![feature(repr_transparent)]
 
 
 #[repr(C)]
diff --git a/src/test/codegen/repr-transparent-aggregates-3.rs b/src/test/codegen/repr-transparent-aggregates-3.rs
index 0c90239..a292f1d 100644
--- a/src/test/codegen/repr-transparent-aggregates-3.rs
+++ b/src/test/codegen/repr-transparent-aggregates-3.rs
@@ -14,7 +14,6 @@
 // See repr-transparent.rs
 
 #![crate_type="lib"]
-#![feature(repr_transparent)]
 
 
 #[repr(C)]
diff --git a/src/test/codegen/repr-transparent-sysv64.rs b/src/test/codegen/repr-transparent-sysv64.rs
index 7a30983..2e4665e 100644
--- a/src/test/codegen/repr-transparent-sysv64.rs
+++ b/src/test/codegen/repr-transparent-sysv64.rs
@@ -13,7 +13,6 @@
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type="lib"]
-#![feature(repr_transparent)]
 
 #[repr(C)]
 pub struct Rgb8 { r: u8, g: u8, b: u8 }
diff --git a/src/test/codegen/repr-transparent.rs b/src/test/codegen/repr-transparent.rs
index 087fa9b..64a62fd 100644
--- a/src/test/codegen/repr-transparent.rs
+++ b/src/test/codegen/repr-transparent.rs
@@ -11,7 +11,7 @@
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type="lib"]
-#![feature(repr_transparent, repr_simd)]
+#![feature(repr_simd)]
 
 use std::marker::PhantomData;
 
diff --git a/src/test/codegen/stack-probes.rs b/src/test/codegen/stack-probes.rs
index 51ebc42..6ab7172 100644
--- a/src/test/codegen/stack-probes.rs
+++ b/src/test/codegen/stack-probes.rs
@@ -13,7 +13,11 @@
 // ignore-mips
 // ignore-mips64
 // ignore-powerpc
+// ignore-powerpc64
+// ignore-powerpc64le
 // ignore-s390x
+// ignore-sparc
+// ignore-sparc64
 // ignore-wasm
 // ignore-emscripten
 // ignore-windows
diff --git a/src/test/codegen/x86_mmx.rs b/src/test/codegen/x86_mmx.rs
index 30777c6..4424c30 100644
--- a/src/test/codegen/x86_mmx.rs
+++ b/src/test/codegen/x86_mmx.rs
@@ -13,6 +13,11 @@
 // ignore-emscripten
 // ignore-mips
 // ignore-mips64
+// ignore-powerpc
+// ignore-powerpc64
+// ignore-powerpc64le
+// ignore-sparc
+// ignore-sparc64
 // compile-flags: -O
 
 #![feature(repr_simd)]
diff --git a/src/test/compile-fail/allocator/auxiliary/system-allocator.rs b/src/test/compile-fail/allocator/auxiliary/system-allocator.rs
index 37e64ba..e5650d5 100644
--- a/src/test/compile-fail/allocator/auxiliary/system-allocator.rs
+++ b/src/test/compile-fail/allocator/auxiliary/system-allocator.rs
@@ -10,7 +10,6 @@
 
 // no-prefer-dynamic
 
-#![feature(global_allocator, allocator_api)]
 #![crate_type = "rlib"]
 
 use std::alloc::System;
diff --git a/src/test/compile-fail/allocator/auxiliary/system-allocator2.rs b/src/test/compile-fail/allocator/auxiliary/system-allocator2.rs
index 37e64ba..e5650d5 100644
--- a/src/test/compile-fail/allocator/auxiliary/system-allocator2.rs
+++ b/src/test/compile-fail/allocator/auxiliary/system-allocator2.rs
@@ -10,7 +10,6 @@
 
 // no-prefer-dynamic
 
-#![feature(global_allocator, allocator_api)]
 #![crate_type = "rlib"]
 
 use std::alloc::System;
diff --git a/src/test/compile-fail/allocator/function-allocator.rs b/src/test/compile-fail/allocator/function-allocator.rs
index 50f8260..989c102 100644
--- a/src/test/compile-fail/allocator/function-allocator.rs
+++ b/src/test/compile-fail/allocator/function-allocator.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(global_allocator)]
 
 #[global_allocator]
 fn foo() {} //~ ERROR: allocators must be statics
diff --git a/src/test/compile-fail/allocator/not-an-allocator.rs b/src/test/compile-fail/allocator/not-an-allocator.rs
index 140cad2..6559335 100644
--- a/src/test/compile-fail/allocator/not-an-allocator.rs
+++ b/src/test/compile-fail/allocator/not-an-allocator.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(global_allocator, heap_api)]
-
 #[global_allocator]
 static A: usize = 0;
 //~^ the trait bound `usize:
diff --git a/src/test/compile-fail/allocator/two-allocators.rs b/src/test/compile-fail/allocator/two-allocators.rs
index 5aa6b5d..7a97a11 100644
--- a/src/test/compile-fail/allocator/two-allocators.rs
+++ b/src/test/compile-fail/allocator/two-allocators.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(global_allocator, allocator_api)]
-
 use std::alloc::System;
 
 #[global_allocator]
diff --git a/src/test/compile-fail/allocator/two-allocators2.rs b/src/test/compile-fail/allocator/two-allocators2.rs
index ec5d985..e747140 100644
--- a/src/test/compile-fail/allocator/two-allocators2.rs
+++ b/src/test/compile-fail/allocator/two-allocators2.rs
@@ -12,8 +12,6 @@
 // no-prefer-dynamic
 // error-pattern: the #[global_allocator] in
 
-#![feature(global_allocator, allocator_api)]
-
 extern crate system_allocator;
 
 use std::alloc::System;
diff --git a/src/test/compile-fail/allocator/two-allocators3.rs b/src/test/compile-fail/allocator/two-allocators3.rs
index c310d94..dd86b02 100644
--- a/src/test/compile-fail/allocator/two-allocators3.rs
+++ b/src/test/compile-fail/allocator/two-allocators3.rs
@@ -13,7 +13,6 @@
 // no-prefer-dynamic
 // error-pattern: the #[global_allocator] in
 
-#![feature(global_allocator)]
 
 extern crate system_allocator;
 extern crate system_allocator2;
diff --git a/src/test/compile-fail/asm-bad-clobber.rs b/src/test/compile-fail/asm-bad-clobber.rs
index aa77e7f..c2b54e3 100644
--- a/src/test/compile-fail/asm-bad-clobber.rs
+++ b/src/test/compile-fail/asm-bad-clobber.rs
@@ -14,7 +14,10 @@
 // ignore-s390x
 // ignore-emscripten
 // ignore-powerpc
+// ignore-powerpc64
+// ignore-powerpc64le
 // ignore-sparc
+// ignore-sparc64
 // ignore-mips
 // ignore-mips64
 
diff --git a/src/test/compile-fail/asm-in-bad-modifier.rs b/src/test/compile-fail/asm-in-bad-modifier.rs
index 5e9278c..2eefd42 100644
--- a/src/test/compile-fail/asm-in-bad-modifier.rs
+++ b/src/test/compile-fail/asm-in-bad-modifier.rs
@@ -11,7 +11,10 @@
 // ignore-s390x
 // ignore-emscripten
 // ignore-powerpc
+// ignore-powerpc64
+// ignore-powerpc64le
 // ignore-sparc
+// ignore-sparc64
 // ignore-mips
 // ignore-mips64
 
diff --git a/src/test/compile-fail/asm-misplaced-option.rs b/src/test/compile-fail/asm-misplaced-option.rs
index abd55ea..bfc1fd6 100644
--- a/src/test/compile-fail/asm-misplaced-option.rs
+++ b/src/test/compile-fail/asm-misplaced-option.rs
@@ -14,7 +14,10 @@
 // ignore-s390x
 // ignore-emscripten
 // ignore-powerpc
+// ignore-powerpc64
+// ignore-powerpc64le
 // ignore-sparc
+// ignore-sparc64
 // ignore-mips
 // ignore-mips64
 
diff --git a/src/test/compile-fail/asm-out-no-modifier.rs b/src/test/compile-fail/asm-out-no-modifier.rs
index 55d8970..40d2ded 100644
--- a/src/test/compile-fail/asm-out-no-modifier.rs
+++ b/src/test/compile-fail/asm-out-no-modifier.rs
@@ -11,7 +11,10 @@
 // ignore-s390x
 // ignore-emscripten
 // ignore-powerpc
+// ignore-powerpc64
+// ignore-powerpc64le
 // ignore-sparc
+// ignore-sparc64
 // ignore-mips
 // ignore-mips64
 
diff --git a/src/test/compile-fail/asm-out-read-uninit.rs b/src/test/compile-fail/asm-out-read-uninit.rs
index c606c5a..c308a9f 100644
--- a/src/test/compile-fail/asm-out-read-uninit.rs
+++ b/src/test/compile-fail/asm-out-read-uninit.rs
@@ -11,7 +11,10 @@
 // ignore-s390x
 // ignore-emscripten
 // ignore-powerpc
+// ignore-powerpc64
+// ignore-powerpc64le
 // ignore-sparc
+// ignore-sparc64
 // ignore-mips
 // ignore-mips64
 
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/compile-fail/auxiliary/some-panic-impl.rs
similarity index 70%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/compile-fail/auxiliary/some-panic-impl.rs
index e7ffbe8..db16ac3 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/compile-fail/auxiliary/some-panic-impl.rs
@@ -8,7 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
+// no-prefer-dynamic
 
-fn main() {}
+#![crate_type = "rlib"]
+#![feature(panic_implementation)]
+#![no_std]
+
+use core::panic::PanicInfo;
+
+#[panic_implementation]
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
diff --git a/src/test/compile-fail/borrowck/borrowck-asm.rs b/src/test/compile-fail/borrowck/borrowck-asm.rs
index 0b230be..d981640 100644
--- a/src/test/compile-fail/borrowck/borrowck-asm.rs
+++ b/src/test/compile-fail/borrowck/borrowck-asm.rs
@@ -11,7 +11,10 @@
 // ignore-s390x
 // ignore-emscripten
 // ignore-powerpc
+// ignore-powerpc64
+// ignore-powerpc64le
 // ignore-sparc
+// ignore-sparc64
 
 // revisions: ast mir
 //[mir]compile-flags: -Z borrowck=mir
diff --git a/src/test/compile-fail/const-array-oob.rs b/src/test/compile-fail/const-array-oob.rs
index 108b794..22a3c5c 100644
--- a/src/test/compile-fail/const-array-oob.rs
+++ b/src/test/compile-fail/const-array-oob.rs
@@ -16,7 +16,7 @@
 const BAR: usize = FOO[5]; // no error, because the error below occurs before regular const eval
 
 const BLUB: [u32; FOO[4]] = [5, 6];
-//~^ ERROR constant evaluation error [E0080]
+//~^ ERROR could not evaluate constant expression [E0080]
 //~| index out of bounds: the len is 3 but the index is 4
 
 fn main() {
diff --git a/src/test/compile-fail/const-err-early.rs b/src/test/compile-fail/const-err-early.rs
index 6caec15..92c6b1f 100644
--- a/src/test/compile-fail/const-err-early.rs
+++ b/src/test/compile-fail/const-err-early.rs
@@ -12,15 +12,15 @@
 
 pub const A: i8 = -std::i8::MIN; //~ ERROR const_err
 //~^ ERROR this constant cannot be used
-//~| ERROR constant evaluation error
+//~| ERROR this expression will panic at runtime
 pub const B: u8 = 200u8 + 200u8; //~ ERROR const_err
 //~^ ERROR this constant cannot be used
 pub const C: u8 = 200u8 * 4; //~ ERROR const_err
 //~^ ERROR this constant cannot be used
 pub const D: u8 = 42u8 - (42u8 + 1); //~ ERROR const_err
 //~^ ERROR this constant cannot be used
-pub const E: u8 = [5u8][1];
-//~^ ERROR const_err
+pub const E: u8 = [5u8][1]; //~ ERROR const_err
+//~| ERROR this constant cannot be used
 
 fn main() {
     let _a = A;
diff --git a/src/test/compile-fail/const-err-multi.rs b/src/test/compile-fail/const-err-multi.rs
index 6f0281b..4a5e78b 100644
--- a/src/test/compile-fail/const-err-multi.rs
+++ b/src/test/compile-fail/const-err-multi.rs
@@ -13,14 +13,17 @@
 pub const A: i8 = -std::i8::MIN;
 //~^ ERROR E0080
 //~| ERROR attempt to negate with overflow
-//~| ERROR constant evaluation error
+//~| ERROR this expression will panic at runtime
 //~| ERROR this constant cannot be used
 pub const B: i8 = A;
 //~^ ERROR const_err
+//~| ERROR const_err
 pub const C: u8 = A as u8;
 //~^ ERROR const_err
+//~| ERROR const_err
 pub const D: i8 = 50 - A;
 //~^ ERROR const_err
+//~| ERROR const_err
 
 fn main() {
     let _ = (A, B, C, D);
diff --git a/src/test/compile-fail/const-err.rs b/src/test/compile-fail/const-err.rs
index f6a64bc..f77603b 100644
--- a/src/test/compile-fail/const-err.rs
+++ b/src/test/compile-fail/const-err.rs
@@ -23,6 +23,7 @@
 // Make sure that the two uses get two errors.
 const FOO: u8 = [5u8][1];
 //~^ ERROR constant evaluation error
+//~| ERROR constant evaluation error
 //~| index out of bounds: the len is 1 but the index is 1
 
 fn main() {
diff --git a/src/test/compile-fail/const-err2.rs b/src/test/compile-fail/const-err2.rs
index 46b7337..9a5cb5a 100644
--- a/src/test/compile-fail/const-err2.rs
+++ b/src/test/compile-fail/const-err2.rs
@@ -31,6 +31,7 @@
     let d = 42u8 - (42u8 + 1);
     //~^ ERROR const_err
     let _e = [5u8][1];
+    //~^ ERROR const_err
     black_box(a);
     black_box(b);
     black_box(c);
diff --git a/src/test/compile-fail/const-err3.rs b/src/test/compile-fail/const-err3.rs
index 9656af6..f5e43b5 100644
--- a/src/test/compile-fail/const-err3.rs
+++ b/src/test/compile-fail/const-err3.rs
@@ -23,6 +23,7 @@
     let d = 42u8 - (42u8 + 1);
     //~^ ERROR const_err
     let _e = [5u8][1];
+    //~^ ERROR const_err
     black_box(b);
     black_box(c);
     black_box(d);
diff --git a/src/test/compile-fail/const-integer-bool-ops.rs b/src/test/compile-fail/const-integer-bool-ops.rs
index 3065122..29bc665 100644
--- a/src/test/compile-fail/const-integer-bool-ops.rs
+++ b/src/test/compile-fail/const-integer-bool-ops.rs
@@ -16,7 +16,6 @@
 //~| ERROR mismatched types
 //~| expected usize, found bool
 const ARR: [i32; X] = [99; 34];
-//~^ ERROR constant evaluation error
 
 const X1: usize = 42 || 39;
 //~^ ERROR mismatched types
@@ -26,7 +25,6 @@
 //~| ERROR mismatched types
 //~| expected usize, found bool
 const ARR1: [i32; X1] = [99; 47];
-//~^ ERROR constant evaluation error
 
 const X2: usize = -42 || -39;
 //~^ ERROR mismatched types
@@ -36,7 +34,6 @@
 //~| ERROR mismatched types
 //~| expected usize, found bool
 const ARR2: [i32; X2] = [99; 18446744073709551607];
-//~^ ERROR constant evaluation error
 
 const X3: usize = -42 && -39;
 //~^ ERROR mismatched types
@@ -46,43 +43,36 @@
 //~| ERROR mismatched types
 //~| expected usize, found bool
 const ARR3: [i32; X3] = [99; 6];
-//~^ ERROR constant evaluation error
 
 const Y: usize = 42.0 == 42.0;
 //~^ ERROR mismatched types
 //~| expected usize, found bool
 const ARRR: [i32; Y] = [99; 1];
-//~^ ERROR constant evaluation error
 
 const Y1: usize = 42.0 >= 42.0;
 //~^ ERROR mismatched types
 //~| expected usize, found bool
 const ARRR1: [i32; Y1] = [99; 1];
-//~^ ERROR constant evaluation error
 
 const Y2: usize = 42.0 <= 42.0;
 //~^ ERROR mismatched types
 //~| expected usize, found bool
 const ARRR2: [i32; Y2] = [99; 1];
-//~^ ERROR constant evaluation error
 
 const Y3: usize = 42.0 > 42.0;
 //~^ ERROR mismatched types
 //~| expected usize, found bool
 const ARRR3: [i32; Y3] = [99; 0];
-//~^ ERROR constant evaluation error
 
 const Y4: usize = 42.0 < 42.0;
 //~^ ERROR mismatched types
 //~| expected usize, found bool
 const ARRR4: [i32; Y4] = [99; 0];
-//~^ ERROR constant evaluation error
 
 const Y5: usize = 42.0 != 42.0;
 //~^ ERROR mismatched types
 //~| expected usize, found bool
 const ARRR5: [i32; Y5] = [99; 0];
-//~^ ERROR constant evaluation error
 
 fn main() {
     let _ = ARR;
diff --git a/src/test/compile-fail/const-len-underflow-subspans.rs b/src/test/compile-fail/const-len-underflow-subspans.rs
index 85cc893..054c272 100644
--- a/src/test/compile-fail/const-len-underflow-subspans.rs
+++ b/src/test/compile-fail/const-len-underflow-subspans.rs
@@ -16,6 +16,6 @@
 
 fn main() {
     let a: [i8; ONE - TWO] = unimplemented!();
-    //~^ ERROR constant evaluation error
+    //~^ ERROR could not evaluate constant expression
     //~| attempt to subtract with overflow
 }
diff --git a/src/test/compile-fail/const-match-check.rs b/src/test/compile-fail/const-match-check.rs
index 36a6600..304eef7 100644
--- a/src/test/compile-fail/const-match-check.rs
+++ b/src/test/compile-fail/const-match-check.rs
@@ -40,5 +40,4 @@
     #[cfg(eval2)]
     let x: [i32; { let 0 = 0; 0 }] = [];
     //[eval2]~^ ERROR refutable pattern in local binding
-    //[eval2]~| ERROR constant evaluation error
 }
diff --git a/src/test/compile-fail/const-tup-index-span.rs b/src/test/compile-fail/const-tup-index-span.rs
index 7596881..b42c440 100644
--- a/src/test/compile-fail/const-tup-index-span.rs
+++ b/src/test/compile-fail/const-tup-index-span.rs
@@ -14,7 +14,6 @@
 //~^ ERROR mismatched types
 //~| expected tuple, found usize
 const ARR: [i32; TUP.0] = [];
-//~^ ERROR constant evaluation error
 
 fn main() {
 }
diff --git a/src/test/compile-fail/duplicate_entry_error.rs b/src/test/compile-fail/duplicate_entry_error.rs
index 485519e..176aa7c 100644
--- a/src/test/compile-fail/duplicate_entry_error.rs
+++ b/src/test/compile-fail/duplicate_entry_error.rs
@@ -14,9 +14,11 @@
 
 #![feature(lang_items)]
 
-#[lang = "panic_fmt"]
-fn panic_fmt() -> ! {
-//~^ ERROR: duplicate lang item found: `panic_fmt`.
+use std::panic::PanicInfo;
+
+#[lang = "panic_impl"]
+fn panic_impl(info: &PanicInfo) -> ! {
+//~^ ERROR: duplicate lang item found: `panic_impl`.
     loop {}
 }
 
diff --git a/src/test/compile-fail/edition-extern-crate-allowed.rs b/src/test/compile-fail/edition-extern-crate-allowed.rs
index 286ee89..7368564 100644
--- a/src/test/compile-fail/edition-extern-crate-allowed.rs
+++ b/src/test/compile-fail/edition-extern-crate-allowed.rs
@@ -12,8 +12,9 @@
 // compile-flags: --edition 2015
 // compile-pass
 
-#![deny(rust_2018_idioms)]
+#![warn(rust_2018_idioms)]
 
 extern crate edition_extern_crate_allowed;
+//~^ WARNING unused extern crate
 
 fn main() {}
diff --git a/src/test/compile-fail/edition-raw-pointer-method-2018.rs b/src/test/compile-fail/edition-raw-pointer-method-2018.rs
index d01cac0..d0cf81d 100644
--- a/src/test/compile-fail/edition-raw-pointer-method-2018.rs
+++ b/src/test/compile-fail/edition-raw-pointer-method-2018.rs
@@ -18,5 +18,5 @@
     let x = 0;
     let y = &x as *const _;
     let _ = y.is_null();
-    //~^ error: the type of this value must be known to call a method on a raw pointer on it [E0908]
+    //~^ error: the type of this value must be known to call a method on a raw pointer on it [E0699]
 }
diff --git a/src/test/compile-fail/eval-enum.rs b/src/test/compile-fail/eval-enum.rs
index 7315616..ada0381 100644
--- a/src/test/compile-fail/eval-enum.rs
+++ b/src/test/compile-fail/eval-enum.rs
@@ -11,12 +11,12 @@
 enum Test {
     DivZero = 1/0,
     //~^ attempt to divide by zero
-    //~| ERROR constant evaluation error
-    //~| ERROR constant evaluation error
+    //~| ERROR could not evaluate enum discriminant
+    //~| ERROR this expression will panic at runtime
     RemZero = 1%0,
     //~^ attempt to calculate the remainder with a divisor of zero
-    //~| ERROR constant evaluation error
-    //~| ERROR constant evaluation error
+    //~| ERROR could not evaluate enum discriminant
+    //~| ERROR this expression will panic at runtime
 }
 
 fn main() {}
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/compile-fail/feature-gate-panic-implementation.rs
similarity index 66%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/compile-fail/feature-gate-panic-implementation.rs
index e7ffbe8..ae9fbc7 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/compile-fail/feature-gate-panic-implementation.rs
@@ -8,7 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
+// compile-flags:-C panic=abort
 
-fn main() {}
+#![no_std]
+#![no_main]
+
+use core::panic::PanicInfo;
+
+#[panic_implementation] //~ ERROR #[panic_implementation] is an unstable feature (see issue #44489)
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
diff --git a/src/test/compile-fail/feature-gate-termination_trait_test.rs b/src/test/compile-fail/feature-gate-termination_trait_test.rs
deleted file mode 100644
index 4af7e94..0000000
--- a/src/test/compile-fail/feature-gate-termination_trait_test.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2017 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: --test
-
-fn main() {}
-
-#[cfg(test)]
-mod tests {
-    #[test]
-    fn it_works() -> Result<(), ()> {
-    //~^ ERROR functions used as tests must have signature fn() -> ()
-        Ok(())
-    }
-}
diff --git a/src/test/compile-fail/issue-39616.rs b/src/test/compile-fail/issue-39616.rs
index d601249c..13b4c08 100644
--- a/src/test/compile-fail/issue-39616.rs
+++ b/src/test/compile-fail/issue-39616.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 fn foo(a: [0; 1]) {} //~ ERROR expected type, found `0`
-//~| ERROR expected one of `->`, `where`, or `{`, found `]`
+//~| ERROR expected one of `)`, `,`, `->`, `where`, or `{`, found `]`
 // FIXME(jseyfried): avoid emitting the second error (preexisting)
 
 fn main() {}
diff --git a/src/test/compile-fail/issue-43105.rs b/src/test/compile-fail/issue-43105.rs
index 6fa65a5..8a04711 100644
--- a/src/test/compile-fail/issue-43105.rs
+++ b/src/test/compile-fail/issue-43105.rs
@@ -12,11 +12,11 @@
 
 const NUM: u8 = xyz();
 //~^ ERROR calls in constants are limited to constant functions, tuple structs and tuple variants
-//~| ERROR constant evaluation error
 
 fn main() {
     match 1 {
         NUM => unimplemented!(),
+        //~^ ERROR could not evaluate constant pattern
         _ => unimplemented!(),
     }
 }
diff --git a/src/test/compile-fail/issue-43988.rs b/src/test/compile-fail/issue-43988.rs
index 0dfa9f6..6361af7 100644
--- a/src/test/compile-fail/issue-43988.rs
+++ b/src/test/compile-fail/issue-43988.rs
@@ -34,6 +34,7 @@
     #[repr]
     let _y = "123";
     //~^^ ERROR attribute should not be applied to a statement
+    //~| WARN `repr` attribute must have a hint
 
 
     fn foo() {}
@@ -44,5 +45,5 @@
 
     let _z = #[repr] 1;
     //~^ ERROR attribute should not be applied to an expression
-
+    //~| WARN `repr` attribute must have a hint
 }
diff --git a/src/test/compile-fail/issue-8460-const.rs b/src/test/compile-fail/issue-8460-const.rs
index 1d59e75..b0d6cb5 100644
--- a/src/test/compile-fail/issue-8460-const.rs
+++ b/src/test/compile-fail/issue-8460-const.rs
@@ -16,62 +16,62 @@
 fn main() {
     assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
-    //~| ERROR constant evaluation error
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
-    //~| ERROR constant evaluation error
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
-    //~| ERROR constant evaluation error
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
-    //~| ERROR constant evaluation error
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
-    //~| ERROR constant evaluation error
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
     //~^ ERROR attempt to divide by zero
-    //~| ERROR constant evaluation error
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
     //~^ ERROR attempt to divide by zero
-    //~| ERROR constant evaluation error
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
     //~^ ERROR attempt to divide by zero
-    //~| ERROR constant evaluation error
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
     //~^ ERROR attempt to divide by zero
-    //~| ERROR constant evaluation error
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
     //~^ ERROR attempt to divide by zero
-    //~| ERROR constant evaluation error
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
-    //~| ERROR constant evaluation error
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
-    //~| ERROR constant evaluation error
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
-    //~| ERROR constant evaluation error
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
-    //~| ERROR constant evaluation error
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
-    //~| ERROR constant evaluation error
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with a divisor of zero
-    //~| ERROR constant evaluation error
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with a divisor of zero
-    //~| ERROR constant evaluation error
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with a divisor of zero
-    //~| ERROR constant evaluation error
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with a divisor of zero
-    //~| ERROR constant evaluation error
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with a divisor of zero
-    //~| ERROR constant evaluation error
+    //~| ERROR this expression will panic at runtime
 }
diff --git a/src/test/compile-fail/lint-stability-fields.rs b/src/test/compile-fail/lint-stability-fields.rs
index 1b605bd..b1b1a9a 100644
--- a/src/test/compile-fail/lint-stability-fields.rs
+++ b/src/test/compile-fail/lint-stability-fields.rs
@@ -18,6 +18,11 @@
 mod cross_crate {
     extern crate lint_stability_fields;
 
+    mod reexport {
+        #[stable(feature = "rust1", since = "1.0.0")]
+        pub use super::lint_stability_fields::*;
+    }
+
     use self::lint_stability_fields::*;
 
     pub fn foo() {
@@ -73,6 +78,8 @@
             // the patterns are all fine:
             { .. } = x;
 
+        // Unstable items are still unstable even when used through a stable "pub use".
+        let x = reexport::Unstable2(1, 2, 3); //~ ERROR use of unstable
 
         let x = Unstable2(1, 2, 3); //~ ERROR use of unstable
 
diff --git a/src/test/compile-fail/macro-non-lifetime.rs b/src/test/compile-fail/macro-non-lifetime.rs
index a2706e8..647d7aa 100644
--- a/src/test/compile-fail/macro-non-lifetime.rs
+++ b/src/test/compile-fail/macro-non-lifetime.rs
@@ -16,5 +16,5 @@
 
 fn main() {
     m!(a);
-    //~^ ERROR expected a lifetime, found `a`
+    //~^ ERROR no rules expected the token `a`
 }
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 72eb687..1c2bf15 100644
--- a/src/test/compile-fail/no_owned_box_lang_item.rs
+++ b/src/test/compile-fail/no_owned_box_lang_item.rs
@@ -21,4 +21,4 @@
 
 #[lang = "eh_personality"] extern fn eh_personality() {}
 #[lang = "eh_unwind_resume"] extern fn eh_unwind_resume() {}
-#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
+#[lang = "panic_impl"] fn panic_impl() -> ! { loop {} }
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/compile-fail/panic-implementation-bad-signature-1.rs
similarity index 63%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/compile-fail/panic-implementation-bad-signature-1.rs
index e7ffbe8..fec11fd 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/compile-fail/panic-implementation-bad-signature-1.rs
@@ -8,7 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
+// compile-flags:-C panic=abort
 
-fn main() {}
+#![feature(panic_implementation)]
+#![no_std]
+#![no_main]
+
+use core::panic::PanicInfo;
+
+#[panic_implementation]
+fn panic(
+    info: PanicInfo, //~ ERROR argument should be `&PanicInfo`
+) -> () //~ ERROR return type should be `!`
+{
+}
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/compile-fail/panic-implementation-bad-signature-2.rs
similarity index 64%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/compile-fail/panic-implementation-bad-signature-2.rs
index e7ffbe8..2a628c0 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/compile-fail/panic-implementation-bad-signature-2.rs
@@ -8,7 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
+// compile-flags:-C panic=abort
 
-fn main() {}
+#![feature(panic_implementation)]
+#![no_std]
+#![no_main]
+
+use core::panic::PanicInfo;
+
+#[panic_implementation]
+fn panic(
+    info: &'static PanicInfo, //~ ERROR argument should be `&PanicInfo`
+) -> !
+{
+    loop {}
+}
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/compile-fail/panic-implementation-bad-signature-3.rs
similarity index 67%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/compile-fail/panic-implementation-bad-signature-3.rs
index e7ffbe8..2933702 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/compile-fail/panic-implementation-bad-signature-3.rs
@@ -8,7 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
+// compile-flags:-C panic=abort
 
-fn main() {}
+#![feature(panic_implementation)]
+#![no_std]
+#![no_main]
+
+use core::panic::PanicInfo;
+
+#[panic_implementation]
+fn panic() -> ! { //~ ERROR function should have one argument
+    loop {}
+}
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/compile-fail/panic-implementation-bad-signature-4.rs
similarity index 62%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/compile-fail/panic-implementation-bad-signature-4.rs
index e7ffbe8..d5f942b 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/compile-fail/panic-implementation-bad-signature-4.rs
@@ -8,7 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
+// compile-flags:-C panic=abort
 
-fn main() {}
+#![feature(panic_implementation)]
+#![no_std]
+#![no_main]
+
+use core::panic::PanicInfo;
+
+#[panic_implementation]
+fn panic<T>(pi: &PanicInfo) -> ! {
+    //~^ ERROR `#[panic_implementation]` function should have no type parameters
+    loop {}
+}
diff --git a/src/test/compile-fail/panic-implementation-duplicate.rs b/src/test/compile-fail/panic-implementation-duplicate.rs
new file mode 100644
index 0000000..017113a
--- /dev/null
+++ b/src/test/compile-fail/panic-implementation-duplicate.rs
@@ -0,0 +1,28 @@
+// Copyright 2018 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 panic=abort
+
+#![feature(lang_items)]
+#![feature(panic_implementation)]
+#![no_std]
+#![no_main]
+
+use core::panic::PanicInfo;
+
+#[panic_implementation]
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
+
+#[lang = "panic_impl"]
+fn panic2(info: &PanicInfo) -> ! { //~ ERROR duplicate lang item found: `panic_impl`.
+    loop {}
+}
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/compile-fail/panic-implementation-requires-panic-info.rs
similarity index 60%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/compile-fail/panic-implementation-requires-panic-info.rs
index e7ffbe8..597f44d 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/compile-fail/panic-implementation-requires-panic-info.rs
@@ -8,7 +8,19 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
+// compile-flags:-C panic=abort
+// error-pattern: language item required, but not found: `panic_info`
 
-fn main() {}
+#![feature(lang_items)]
+#![feature(no_core)]
+#![feature(panic_implementation)]
+#![no_core]
+#![no_main]
+
+#[panic_implementation]
+fn panic() -> ! {
+    loop {}
+}
+
+#[lang = "sized"]
+trait Sized {}
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/compile-fail/panic-implementation-std.rs
similarity index 70%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/compile-fail/panic-implementation-std.rs
index e7ffbe8..f25cd36 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/compile-fail/panic-implementation-std.rs
@@ -8,7 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
+// error-pattern: duplicate lang item found: `panic_impl`.
+
+#![feature(panic_implementation)]
+
+use std::panic::PanicInfo;
+
+#[panic_implementation]
+fn panic(info: PanicInfo) -> ! {
+    loop {}
+}
 
 fn main() {}
diff --git a/src/test/compile-fail/panic-implementation-twice.rs b/src/test/compile-fail/panic-implementation-twice.rs
new file mode 100644
index 0000000..78dc545
--- /dev/null
+++ b/src/test/compile-fail/panic-implementation-twice.rs
@@ -0,0 +1,29 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:some-panic-impl.rs
+
+#![feature(panic_implementation)]
+#![feature(lang_items)]
+#![no_std]
+#![no_main]
+
+extern crate some_panic_impl;
+
+use core::panic::PanicInfo;
+
+#[panic_implementation]
+fn panic(info: &PanicInfo) -> ! {
+    //~^ error duplicate lang item found: `panic_impl`
+    loop {}
+}
+
+#[lang = "eh_personality"]
+fn eh() {}
diff --git a/src/test/compile-fail/panic-runtime/auxiliary/panic-runtime-lang-items.rs b/src/test/compile-fail/panic-runtime/auxiliary/panic-runtime-lang-items.rs
index fbf70b3..d9848a5 100644
--- a/src/test/compile-fail/panic-runtime/auxiliary/panic-runtime-lang-items.rs
+++ b/src/test/compile-fail/panic-runtime/auxiliary/panic-runtime-lang-items.rs
@@ -15,8 +15,10 @@
 #![no_std]
 #![feature(lang_items)]
 
-#[lang = "panic_fmt"]
-fn panic_fmt() {}
+use core::panic::PanicInfo;
+
+#[lang = "panic_impl"]
+fn panic_impl(info: &PanicInfo) -> ! { loop {} }
 #[lang = "eh_personality"]
 fn eh_personality() {}
 #[lang = "eh_unwind_resume"]
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/compile-fail/panic_implementation-closures.rs
similarity index 70%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/compile-fail/panic_implementation-closures.rs
index e7ffbe8..4fa9a63 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/compile-fail/panic_implementation-closures.rs
@@ -8,7 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
+// compile-pass
 
-fn main() {}
+#![crate_type = "rlib"]
+#![no_std]
+#![feature(panic_implementation)]
+
+#[panic_implementation]
+pub fn panic_fmt(_: &::core::panic::PanicInfo) -> ! {
+    |x: u8| x;
+    loop {}
+}
diff --git a/src/test/compile-fail/repr-transparent-other-items.rs b/src/test/compile-fail/repr-transparent-other-items.rs
index cf08708..685d62d 100644
--- a/src/test/compile-fail/repr-transparent-other-items.rs
+++ b/src/test/compile-fail/repr-transparent-other-items.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(repr_transparent)]
-
 // See also repr-transparent.rs
 
 #[repr(transparent)] //~ ERROR unsupported representation for zero-variant enum
diff --git a/src/test/compile-fail/repr-transparent-other-reprs.rs b/src/test/compile-fail/repr-transparent-other-reprs.rs
index 7b91a6f..a391c0a 100644
--- a/src/test/compile-fail/repr-transparent-other-reprs.rs
+++ b/src/test/compile-fail/repr-transparent-other-reprs.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(repr_transparent, repr_align, attr_literals)]
+#![feature(repr_align, attr_literals)]
 
 // See also repr-transparent.rs
 
diff --git a/src/test/compile-fail/repr-transparent.rs b/src/test/compile-fail/repr-transparent.rs
index b5e6a0f..4d8ec4c 100644
--- a/src/test/compile-fail/repr-transparent.rs
+++ b/src/test/compile-fail/repr-transparent.rs
@@ -14,7 +14,6 @@
 // - repr-transparent-other-items.rs
 
 #![feature(repr_align, attr_literals)]
-#![feature(repr_transparent)]
 
 use std::marker::PhantomData;
 
diff --git a/src/test/compile-fail/rfc-2008-non-exhaustive/invalid-attribute.rs b/src/test/compile-fail/rfc-2008-non-exhaustive/invalid-attribute.rs
index e48d989..df4fe1e 100644
--- a/src/test/compile-fail/rfc-2008-non-exhaustive/invalid-attribute.rs
+++ b/src/test/compile-fail/rfc-2008-non-exhaustive/invalid-attribute.rs
@@ -11,15 +11,15 @@
 #![feature(non_exhaustive)]
 
 #[non_exhaustive(anything)]
-//~^ ERROR attribute should be empty [E0911]
+//~^ ERROR attribute should be empty [E0702]
 struct Foo;
 
 #[non_exhaustive]
-//~^ ERROR attribute can only be applied to a struct or enum [E0910]
+//~^ ERROR attribute can only be applied to a struct or enum [E0701]
 trait Bar { }
 
 #[non_exhaustive]
-//~^ ERROR attribute can only be applied to a struct or enum [E0910]
+//~^ ERROR attribute can only be applied to a struct or enum [E0701]
 union Baz {
     f1: u16,
     f2: u16
diff --git a/src/test/compile-fail/weak-lang-item.rs b/src/test/compile-fail/weak-lang-item.rs
index 8579611..7b988c3 100644
--- a/src/test/compile-fail/weak-lang-item.rs
+++ b/src/test/compile-fail/weak-lang-item.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // aux-build:weak-lang-items.rs
-// error-pattern: language item required, but not found: `panic_fmt`
+// error-pattern: language item required, but not found: `panic_impl`
 // error-pattern: language item required, but not found: `eh_personality`
 // ignore-wasm32-bare compiled with panic=abort, personality not required
 
diff --git a/src/test/incremental/hashes/function_interfaces.rs b/src/test/incremental/hashes/function_interfaces.rs
index 09cc538..03860ae 100644
--- a/src/test/incremental/hashes/function_interfaces.rs
+++ b/src/test/incremental/hashes/function_interfaces.rs
@@ -284,7 +284,7 @@
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody")]
+#[rustc_clean(cfg = "cfail2")]
 #[rustc_clean(cfg = "cfail3")]
 pub fn change_return_impl_trait() -> impl Copy {
     0u32
diff --git a/src/test/incremental/issue-51409.rs b/src/test/incremental/issue-51409.rs
new file mode 100644
index 0000000..d7aff5a
--- /dev/null
+++ b/src/test/incremental/issue-51409.rs
@@ -0,0 +1,22 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// revisions: rpass1
+
+// Regression test that `infer_outlives_predicates` can be
+// used with incremental without an ICE.
+
+#![feature(infer_outlives_requirements)]
+
+struct Foo<'a, T> {
+  x: &'a T
+}
+
+fn main() { }
diff --git a/src/test/parse-fail/bind-struct-early-modifiers.rs b/src/test/parse-fail/bind-struct-early-modifiers.rs
index 25348a3..e9e76af 100644
--- a/src/test/parse-fail/bind-struct-early-modifiers.rs
+++ b/src/test/parse-fail/bind-struct-early-modifiers.rs
@@ -13,7 +13,7 @@
 fn main() {
     struct Foo { x: isize }
     match (Foo { x: 10 }) {
-        Foo { ref x: ref x } => {}, //~ ERROR expected `,`, found `:`
+        Foo { ref x: ref x } => {}, //~ ERROR expected `,`
         _ => {}
     }
 }
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/parse-fail/trait-plusequal-splitting.rs
similarity index 66%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/parse-fail/trait-plusequal-splitting.rs
index e7ffbe8..cbb955f 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/parse-fail/trait-plusequal-splitting.rs
@@ -8,7 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
+// compile-flags: -Z parse-only
+// Fixes issue where `+` in generics weren't parsed if they were part of a `+=`.
 
-fn main() {}
+struct Whitespace<T: Clone + = ()> { t: T }
+struct TokenSplit<T: Clone +=  ()> { t: T }
+
+fn main() {
+}
+
+FAIL //~ ERROR
diff --git a/src/test/run-fail/mir_indexing_oob_1.rs b/src/test/run-fail/mir_indexing_oob_1.rs
index 41ff466..cf342ad 100644
--- a/src/test/run-fail/mir_indexing_oob_1.rs
+++ b/src/test/run-fail/mir_indexing_oob_1.rs
@@ -12,6 +12,7 @@
 
 const C: [u32; 5] = [0; 5];
 
+#[allow(const_err)]
 fn test() -> u32 {
     C[10]
 }
diff --git a/src/test/run-fail/mir_indexing_oob_2.rs b/src/test/run-fail/mir_indexing_oob_2.rs
index c5c8234..3eb9468 100644
--- a/src/test/run-fail/mir_indexing_oob_2.rs
+++ b/src/test/run-fail/mir_indexing_oob_2.rs
@@ -12,6 +12,7 @@
 
 const C: &'static [u8; 5] = b"hello";
 
+#[allow(const_err)]
 fn test() -> u8 {
     C[10]
 }
diff --git a/src/test/run-fail/mir_indexing_oob_3.rs b/src/test/run-fail/mir_indexing_oob_3.rs
index 9bc4b00..06bb6d4 100644
--- a/src/test/run-fail/mir_indexing_oob_3.rs
+++ b/src/test/run-fail/mir_indexing_oob_3.rs
@@ -12,6 +12,7 @@
 
 const C: &'static [u8; 5] = b"hello";
 
+#[allow(const_err)]
 fn mir() -> u8 {
     C[10]
 }
diff --git a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
index 251fb78..439bc01 100644
--- a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
+++ b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
@@ -20,7 +20,7 @@
 use rustc::session::{Session, CompileIncomplete};
 use rustc::session::config::OutputFilenames;
 use rustc::ty::TyCtxt;
-use rustc::ty::maps::Providers;
+use rustc::ty::query::Providers;
 use rustc::middle::cstore::MetadataLoader;
 use rustc::dep_graph::DepGraph;
 use rustc_codegen_utils::codegen_backend::{CodegenBackend, MetadataOnlyCodegenBackend};
diff --git a/src/test/run-make-fulldeps/issue-19371/foo.rs b/src/test/run-make-fulldeps/issue-19371/foo.rs
index 403f4f7..6f5e2af 100644
--- a/src/test/run-make-fulldeps/issue-19371/foo.rs
+++ b/src/test/run-make-fulldeps/issue-19371/foo.rs
@@ -19,9 +19,9 @@
 extern crate syntax;
 
 use rustc::session::{build_session, Session};
-use rustc::session::config::{basic_options, Input,
+use rustc::session::config::{basic_options, Input, Options,
                              OutputType, OutputTypes};
-use rustc_driver::driver::{compile_input, CompileController};
+use rustc_driver::driver::{self, compile_input, CompileController};
 use rustc_metadata::cstore::CStore;
 use rustc_errors::registry::Registry;
 use syntax::codemap::FileName;
@@ -52,14 +52,7 @@
     compile(src.to_string(), tmpdir.join("out"), sysroot.clone());
 }
 
-fn basic_sess(sysroot: PathBuf) -> (Session, Rc<CStore>, Box<CodegenBackend>) {
-    let mut opts = basic_options();
-    opts.output_types = OutputTypes::new(&[(OutputType::Exe, None)]);
-    opts.maybe_sysroot = Some(sysroot);
-    if let Ok(linker) = std::env::var("RUSTC_LINKER") {
-        opts.cg.linker = Some(linker.into());
-    }
-
+fn basic_sess(opts: Options) -> (Session, Rc<CStore>, Box<CodegenBackend>) {
     let descriptions = Registry::new(&rustc::DIAGNOSTICS);
     let sess = build_session(opts, None, descriptions);
     let codegen_backend = rustc_driver::get_codegen_backend(&sess);
@@ -70,19 +63,27 @@
 
 fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
     syntax::with_globals(|| {
-        let (sess, cstore, codegen_backend) = basic_sess(sysroot);
-        let control = CompileController::basic();
-        let input = Input::Str { name: FileName::Anon, input: code };
-        let _ = compile_input(
-            codegen_backend,
-            &sess,
-            &cstore,
-            &None,
-            &input,
-            &None,
-            &Some(output),
-            None,
-            &control
-        );
+        let mut opts = basic_options();
+        opts.output_types = OutputTypes::new(&[(OutputType::Exe, None)]);
+        opts.maybe_sysroot = Some(sysroot);
+        if let Ok(linker) = std::env::var("RUSTC_LINKER") {
+            opts.cg.linker = Some(linker.into());
+        }
+        driver::spawn_thread_pool(opts, |opts| {
+            let (sess, cstore, codegen_backend) = basic_sess(opts);
+            let control = CompileController::basic();
+            let input = Input::Str { name: FileName::Anon, input: code };
+            let _ = compile_input(
+                codegen_backend,
+                &sess,
+                &cstore,
+                &None,
+                &input,
+                &None,
+                &Some(output),
+                None,
+                &control
+            );
+        });
     });
 }
diff --git a/src/test/run-make-fulldeps/issue-36710/Makefile b/src/test/run-make-fulldeps/issue-36710/Makefile
new file mode 100644
index 0000000..928bdf5
--- /dev/null
+++ b/src/test/run-make-fulldeps/issue-36710/Makefile
@@ -0,0 +1,21 @@
+-include ../tools.mk
+
+ifeq (musl,$(findstring musl,$(TARGET)))
+all: skip
+else
+all: test
+endif
+
+test: foo
+	$(call RUN,foo)
+
+skip:
+	echo "expected failure"
+
+foo: foo.rs $(call NATIVE_STATICLIB,foo)
+	$(RUSTC) $< -lfoo $(EXTRACXXFLAGS)
+
+$(TMPDIR)/libfoo.o: foo.cpp
+	$(call COMPILE_OBJ_CXX,$@,$<)
+
+.PHONY: all test skip
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/run-make-fulldeps/issue-36710/foo.cpp
similarity index 73%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/run-make-fulldeps/issue-36710/foo.cpp
index e7ffbe8..fbd0ead 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/run-make-fulldeps/issue-36710/foo.cpp
@@ -8,7 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
+#include <stdint.h>
 
-fn main() {}
+struct A {
+    A() { v = 1234; }
+    ~A() { v = 1; }
+    uint32_t v;
+};
+
+A a;
+
+extern "C" {
+    uint32_t get() {
+        return a.v;
+    }
+}
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/run-make-fulldeps/issue-36710/foo.rs
similarity index 73%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/run-make-fulldeps/issue-36710/foo.rs
index e7ffbe8..6e50566 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/run-make-fulldeps/issue-36710/foo.rs
@@ -8,7 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
+// Tests that linking to C++ code with global destructors works.
 
-fn main() {}
+extern { fn get() -> u32; }
+
+fn main() {
+    let i = unsafe { get() };
+    assert_eq!(i, 1234);
+}
diff --git a/src/test/run-make-fulldeps/panic-impl-transitive/Makefile b/src/test/run-make-fulldeps/panic-impl-transitive/Makefile
new file mode 100644
index 0000000..1714578
--- /dev/null
+++ b/src/test/run-make-fulldeps/panic-impl-transitive/Makefile
@@ -0,0 +1,7 @@
+-include ../../run-make-fulldeps/tools.mk
+
+# NOTE we use --emit=llvm-ir to avoid running the linker (linking will fail because there's no main
+# in this crate)
+all:
+	$(RUSTC) panic-impl-provider.rs
+	$(RUSTC) panic-impl-consumer.rs -C panic=abort --emit=llvm-ir -L $(TMPDIR)
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/run-make-fulldeps/panic-impl-transitive/panic-impl-consumer.rs
similarity index 76%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/run-make-fulldeps/panic-impl-transitive/panic-impl-consumer.rs
index e7ffbe8..592fab8 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/run-make-fulldeps/panic-impl-transitive/panic-impl-consumer.rs
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
+#![no_std]
+#![no_main]
 
-fn main() {}
+// this crate provides the `panic_impl` lang item so we don't need to define it here
+extern crate panic_impl_provider;
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/run-make-fulldeps/panic-impl-transitive/panic-impl-provider.rs
similarity index 72%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/run-make-fulldeps/panic-impl-transitive/panic-impl-provider.rs
index e7ffbe8..46cdf2e 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/run-make-fulldeps/panic-impl-transitive/panic-impl-provider.rs
@@ -8,7 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
+#![crate_type = "rlib"]
+#![feature(panic_implementation)]
+#![no_std]
 
-fn main() {}
+use core::panic::PanicInfo;
+
+#[panic_implementation]
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
diff --git a/src/test/run-make-fulldeps/std-core-cycle/bar.rs b/src/test/run-make-fulldeps/std-core-cycle/bar.rs
index 62fd2ad..4b885e5 100644
--- a/src/test/run-make-fulldeps/std-core-cycle/bar.rs
+++ b/src/test/run-make-fulldeps/std-core-cycle/bar.rs
@@ -16,11 +16,11 @@
 pub struct A;
 
 unsafe impl GlobalAlloc for A {
-    unsafe fn alloc(&self, _: Layout) -> *mut Opaque {
+    unsafe fn alloc(&self, _: Layout) -> *mut u8 {
         loop {}
     }
 
-    unsafe fn dealloc(&self, _ptr: *mut Opaque, _: Layout) {
+    unsafe fn dealloc(&self, _ptr: *mut u8, _: Layout) {
         loop {}
     }
 }
diff --git a/src/test/run-make-fulldeps/std-core-cycle/foo.rs b/src/test/run-make-fulldeps/std-core-cycle/foo.rs
index 04742bb..46047fb 100644
--- a/src/test/run-make-fulldeps/std-core-cycle/foo.rs
+++ b/src/test/run-make-fulldeps/std-core-cycle/foo.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(global_allocator)]
 #![crate_type = "cdylib"]
 
 extern crate bar;
diff --git a/src/test/run-make-fulldeps/tools.mk b/src/test/run-make-fulldeps/tools.mk
index af1707d..3de358f 100644
--- a/src/test/run-make-fulldeps/tools.mk
+++ b/src/test/run-make-fulldeps/tools.mk
@@ -59,12 +59,14 @@
 
 ifdef IS_MSVC
 COMPILE_OBJ = $(CC) -c -Fo:`cygpath -w $(1)` $(2)
+COMPILE_OBJ_CXX = $(CXX) -c -Fo:`cygpath -w $(1)` $(2)
 NATIVE_STATICLIB_FILE = $(1).lib
 NATIVE_STATICLIB = $(TMPDIR)/$(call NATIVE_STATICLIB_FILE,$(1))
 OUT_EXE=-Fe:`cygpath -w $(TMPDIR)/$(call BIN,$(1))` \
 	-Fo:`cygpath -w $(TMPDIR)/$(1).obj`
 else
 COMPILE_OBJ = $(CC) -c -o $(1) $(2)
+COMPILE_OBJ_CXX = $(CXX) -c -o $(1) $(2)
 NATIVE_STATICLIB_FILE = lib$(1).a
 NATIVE_STATICLIB = $(call STATICLIB,$(1))
 OUT_EXE=-o $(TMPDIR)/$(1)
diff --git a/src/test/run-pass-fulldeps/compiler-calls.rs b/src/test/run-pass-fulldeps/compiler-calls.rs
index 9aa4f42..b3a6fb4 100644
--- a/src/test/run-pass-fulldeps/compiler-calls.rs
+++ b/src/test/run-pass-fulldeps/compiler-calls.rs
@@ -31,11 +31,11 @@
 
 use std::path::PathBuf;
 
-struct TestCalls {
-    count: u32
+struct TestCalls<'a> {
+    count: &'a mut u32
 }
 
-impl<'a> CompilerCalls<'a> for TestCalls {
+impl<'a> CompilerCalls<'a> for TestCalls<'a> {
     fn early_callback(&mut self,
                       _: &getopts::Matches,
                       _: &config::Options,
@@ -43,7 +43,7 @@
                       _: &errors::registry::Registry,
                       _: config::ErrorOutputType)
                       -> Compilation {
-        self.count *= 2;
+        *self.count *= 2;
         Compilation::Continue
     }
 
@@ -56,13 +56,13 @@
                      _: &Option<PathBuf>,
                      _: &Option<PathBuf>)
                      -> Compilation {
-        self.count *= 3;
+        *self.count *= 3;
         Compilation::Stop
     }
 
     fn some_input(&mut self, input: Input, input_path: Option<PathBuf>)
                   -> (Input, Option<PathBuf>) {
-        self.count *= 5;
+        *self.count *= 5;
         (input, input_path)
     }
 
@@ -77,7 +77,7 @@
         panic!("This shouldn't happen");
     }
 
-    fn build_controller(&mut self,
+    fn build_controller(self: Box<Self>,
                         _: &Session,
                         _: &getopts::Matches)
                         -> driver::CompileController<'a> {
@@ -87,9 +87,12 @@
 
 
 fn main() {
-    let mut tc = TestCalls { count: 1 };
-    // we should never get use this filename, but lets make sure they are valid args.
-    let args = vec!["compiler-calls".to_string(), "foo.rs".to_string()];
-    rustc_driver::run_compiler(&args, &mut tc, None, None);
-    assert_eq!(tc.count, 30);
+    let mut count = 1;
+    {
+        let tc = TestCalls { count: &mut count };
+        // we should never get use this filename, but lets make sure they are valid args.
+        let args = vec!["compiler-calls".to_string(), "foo.rs".to_string()];
+        rustc_driver::run_compiler(&args, Box::new(tc), None, None);
+    }
+    assert_eq!(count, 30);
 }
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/double.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/double.rs
index f4404b7..a6c9817 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/double.rs
+++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/double.rs
@@ -16,6 +16,8 @@
 
 use proc_macro::TokenStream;
 
+// Outputs another copy of the struct.  Useful for testing the tokens
+// seen by the proc_macro.
 #[proc_macro_derive(Double)]
 pub fn derive(input: TokenStream) -> TokenStream {
     format!("mod foo {{ {} }}", input.to_string()).parse().unwrap()
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/external-crate-var.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/external-crate-var.rs
new file mode 100644
index 0000000..030c53b
--- /dev/null
+++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/external-crate-var.rs
@@ -0,0 +1,51 @@
+// Copyright 2016 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 ExternFoo;
+
+pub trait ExternTrait {
+    const CONST: u32;
+    type Assoc;
+}
+
+impl ExternTrait for ExternFoo {
+    const CONST: u32 = 0;
+    type Assoc = ExternFoo;
+}
+
+#[macro_export]
+macro_rules! external { () => {
+    mod bar {
+        #[derive(Double)]
+        struct Bar($crate::ExternFoo);
+    }
+
+    mod qself {
+        #[derive(Double)]
+        struct QSelf(<$crate::ExternFoo as $crate::ExternTrait>::Assoc);
+    }
+
+    mod qself_recurse {
+        #[derive(Double)]
+        struct QSelfRecurse(<
+            <$crate::ExternFoo as $crate::ExternTrait>::Assoc
+            as $crate::ExternTrait>::Assoc
+        );
+    }
+
+    mod qself_in_const {
+        #[derive(Double)]
+        #[repr(u32)]
+        enum QSelfInConst {
+            Variant = <$crate::ExternFoo as $crate::ExternTrait>::CONST,
+        }
+    }
+} }
+
diff --git a/src/test/run-pass-fulldeps/proc-macro/crate-var.rs b/src/test/run-pass-fulldeps/proc-macro/crate-var.rs
index b6acb0f..41c1519 100644
--- a/src/test/run-pass-fulldeps/proc-macro/crate-var.rs
+++ b/src/test/run-pass-fulldeps/proc-macro/crate-var.rs
@@ -9,19 +9,63 @@
 // except according to those terms.
 
 // aux-build:double.rs
+// aux-build:external-crate-var.rs
 // ignore-stage1
 
 #![allow(unused)]
 
 #[macro_use]
 extern crate double;
+#[macro_use]
+extern crate external_crate_var;
 
 struct Foo;
 
-macro_rules! m { () => {
-    #[derive(Double)]
-    struct Bar($crate::Foo);
+trait Trait {
+    const CONST: u32;
+    type Assoc;
+}
+
+impl Trait for Foo {
+    const CONST: u32 = 0;
+    type Assoc = Foo;
+}
+
+macro_rules! local { () => {
+    // derive_Double outputs secondary copies of each definition
+    // to test what the proc_macro sees.
+    mod bar {
+        #[derive(Double)]
+        struct Bar($crate::Foo);
+    }
+
+    mod qself {
+        #[derive(Double)]
+        struct QSelf(<::Foo as $crate::Trait>::Assoc);
+    }
+
+    mod qself_recurse {
+        #[derive(Double)]
+        struct QSelfRecurse(<<$crate::Foo as $crate::Trait>::Assoc as $crate::Trait>::Assoc);
+    }
+
+    mod qself_in_const {
+        #[derive(Double)]
+        #[repr(u32)]
+        enum QSelfInConst {
+            Variant = <::Foo as $crate::Trait>::CONST,
+        }
+    }
 } }
-m!();
+
+mod local {
+    local!();
+}
+
+// and now repeat the above tests, using a macro defined in another crate
+
+mod external {
+    external!{}
+}
 
 fn main() {}
diff --git a/src/test/run-pass-valgrind/issue-44800.rs b/src/test/run-pass-valgrind/issue-44800.rs
index cfde6f3..29cfae1 100644
--- a/src/test/run-pass-valgrind/issue-44800.rs
+++ b/src/test/run-pass-valgrind/issue-44800.rs
@@ -8,11 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(global_allocator, alloc_system, allocator_api)]
-extern crate alloc_system;
-
+use std::alloc::System;
 use std::collections::VecDeque;
-use alloc_system::System;
 
 #[global_allocator]
 static ALLOCATOR: System = System;
diff --git a/src/test/run-pass/allocator/auxiliary/custom-as-global.rs b/src/test/run-pass/allocator/auxiliary/custom-as-global.rs
index 538f36f..a3f05a0 100644
--- a/src/test/run-pass/allocator/auxiliary/custom-as-global.rs
+++ b/src/test/run-pass/allocator/auxiliary/custom-as-global.rs
@@ -10,7 +10,6 @@
 
 // no-prefer-dynamic
 
-#![feature(global_allocator)]
 #![crate_type = "rlib"]
 
 extern crate custom;
diff --git a/src/test/run-pass/allocator/auxiliary/custom.rs b/src/test/run-pass/allocator/auxiliary/custom.rs
index 91f70aa..02e86fa 100644
--- a/src/test/run-pass/allocator/auxiliary/custom.rs
+++ b/src/test/run-pass/allocator/auxiliary/custom.rs
@@ -13,18 +13,18 @@
 #![feature(heap_api, allocator_api)]
 #![crate_type = "rlib"]
 
-use std::alloc::{GlobalAlloc, System, Layout, Opaque};
+use std::alloc::{GlobalAlloc, System, Layout};
 use std::sync::atomic::{AtomicUsize, Ordering};
 
 pub struct A(pub AtomicUsize);
 
 unsafe impl GlobalAlloc for A {
-    unsafe fn alloc(&self, layout: Layout) -> *mut Opaque {
+    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
         self.0.fetch_add(1, Ordering::SeqCst);
         System.alloc(layout)
     }
 
-    unsafe fn dealloc(&self, ptr: *mut Opaque, layout: Layout) {
+    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
         self.0.fetch_add(1, Ordering::SeqCst);
         System.dealloc(ptr, layout)
     }
diff --git a/src/test/run-pass/allocator/custom.rs b/src/test/run-pass/allocator/custom.rs
index 415d39a..3a7f8fa 100644
--- a/src/test/run-pass/allocator/custom.rs
+++ b/src/test/run-pass/allocator/custom.rs
@@ -11,11 +11,11 @@
 // aux-build:helper.rs
 // no-prefer-dynamic
 
-#![feature(global_allocator, heap_api, allocator_api)]
+#![feature(allocator_api)]
 
 extern crate helper;
 
-use std::alloc::{self, Global, Alloc, System, Layout, Opaque};
+use std::alloc::{self, Global, Alloc, System, Layout};
 use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
 
 static HITS: AtomicUsize = ATOMIC_USIZE_INIT;
@@ -23,12 +23,12 @@
 struct A;
 
 unsafe impl alloc::GlobalAlloc for A {
-    unsafe fn alloc(&self, layout: Layout) -> *mut Opaque {
+    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
         HITS.fetch_add(1, Ordering::SeqCst);
         System.alloc(layout)
     }
 
-    unsafe fn dealloc(&self, ptr: *mut Opaque, layout: Layout) {
+    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
         HITS.fetch_add(1, Ordering::SeqCst);
         System.dealloc(ptr, layout)
     }
diff --git a/src/test/run-pass/allocator/xcrate-use.rs b/src/test/run-pass/allocator/xcrate-use.rs
index 78d604a..482e3b0 100644
--- a/src/test/run-pass/allocator/xcrate-use.rs
+++ b/src/test/run-pass/allocator/xcrate-use.rs
@@ -12,7 +12,7 @@
 // aux-build:helper.rs
 // no-prefer-dynamic
 
-#![feature(global_allocator, heap_api, allocator_api)]
+#![feature(allocator_api)]
 
 extern crate custom;
 extern crate helper;
diff --git a/src/test/run-pass/allocator/xcrate-use2.rs b/src/test/run-pass/allocator/xcrate-use2.rs
index b8e8445..fbde7e8 100644
--- a/src/test/run-pass/allocator/xcrate-use2.rs
+++ b/src/test/run-pass/allocator/xcrate-use2.rs
@@ -19,7 +19,7 @@
 extern crate custom_as_global;
 extern crate helper;
 
-use std::alloc::{Global, Alloc, GlobalAlloc, System, Layout};
+use std::alloc::{alloc, dealloc, GlobalAlloc, System, Layout};
 use std::sync::atomic::{Ordering, ATOMIC_USIZE_INIT};
 
 static GLOBAL: custom::A = custom::A(ATOMIC_USIZE_INIT);
@@ -30,10 +30,10 @@
         let layout = Layout::from_size_align(4, 2).unwrap();
 
         // Global allocator routes to the `custom_as_global` global
-        let ptr = Global.alloc(layout.clone());
+        let ptr = alloc(layout.clone());
         helper::work_with(&ptr);
         assert_eq!(custom_as_global::get(), n + 1);
-        Global.dealloc(ptr, layout.clone());
+        dealloc(ptr, layout.clone());
         assert_eq!(custom_as_global::get(), n + 2);
 
         // Usage of the system allocator avoids all globals
diff --git a/src/test/run-pass/auxiliary/issue_38715.rs b/src/test/run-pass/auxiliary/issue_38715.rs
index cad3996..cf4fee0 100644
--- a/src/test/run-pass/auxiliary/issue_38715.rs
+++ b/src/test/run-pass/auxiliary/issue_38715.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![allow(duplicate_macro_exports)]
+
 #[macro_export]
 macro_rules! foo { ($i:ident) => {} }
 
diff --git a/src/test/parse-fail/removed-syntax-fn-pure.rs b/src/test/run-pass/auxiliary/two_macros_2.rs
similarity index 70%
rename from src/test/parse-fail/removed-syntax-fn-pure.rs
rename to src/test/run-pass/auxiliary/two_macros_2.rs
index 83794a7..b16cd3a 100644
--- a/src/test/parse-fail/removed-syntax-fn-pure.rs
+++ b/src/test/run-pass/auxiliary/two_macros_2.rs
@@ -1,4 +1,4 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,6 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags: -Z parse-only
+macro_rules! macro_one { ($($t:tt)*) => ($($t)*) }
 
-pure fn f() {} //~ ERROR expected item, found `pure`
+macro_rules! macro_two { ($($t:tt)*) => ($($t)*) }
diff --git a/src/test/run-pass/borrowck/borrowck-multiple-borrows-interior-boxes.rs b/src/test/run-pass/borrowck/borrowck-multiple-borrows-interior-boxes.rs
new file mode 100644
index 0000000..f57a7bd
--- /dev/null
+++ b/src/test/run-pass/borrowck/borrowck-multiple-borrows-interior-boxes.rs
@@ -0,0 +1,29 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test case from #39963.
+
+#![feature(nll)]
+
+#[derive(Clone)]
+struct Foo(Option<Box<Foo>>, Option<Box<Foo>>);
+
+fn test(f: &mut Foo) {
+  match *f {
+    Foo(Some(ref mut left), Some(ref mut right)) => match **left {
+      Foo(Some(ref mut left), Some(ref mut right)) => panic!(),
+      _ => panic!(),
+    },
+    _ => panic!(),
+  }
+}
+
+fn main() {
+}
diff --git a/src/test/run-pass/const-endianess.rs b/src/test/run-pass/const-endianess.rs
new file mode 100644
index 0000000..fa34b49
--- /dev/null
+++ b/src/test/run-pass/const-endianess.rs
@@ -0,0 +1,32 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(const_int_ops)]
+#![feature(test)]
+
+extern crate test;
+use test::black_box as b;
+
+const BE_U32: u32 = 55u32.to_be();
+const LE_U32: u32 = 55u32.to_le();
+
+
+fn main() {
+    assert_eq!(BE_U32, b(55u32).to_be());
+    assert_eq!(LE_U32, b(55u32).to_le());
+
+    #[cfg(not(target_arch = "asmjs"))]
+    {
+        const BE_U128: u128 = 999999u128.to_be();
+        const LE_I128: i128 = -999999i128.to_le();
+        assert_eq!(BE_U128, b(999999u128).to_be());
+        assert_eq!(LE_I128, b(-999999i128).to_le());
+    }
+}
diff --git a/src/test/run-pass/ctfe/union-ice.rs b/src/test/run-pass/ctfe/union-ice.rs
deleted file mode 100644
index f83f49f..0000000
--- a/src/test/run-pass/ctfe/union-ice.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![feature(const_fn)]
-
-type Field1 = i32;
-type Field2 = f32;
-type Field3 = i64;
-
-union DummyUnion {
-    field1: Field1,
-    field2: Field2,
-    field3: Field3,
-}
-
-const FLOAT1_AS_I32: i32 = 1065353216;
-const UNION: DummyUnion = DummyUnion { field1: FLOAT1_AS_I32 };
-
-const fn read_field1() -> Field1 {
-    const FIELD1: Field1 = unsafe { UNION.field1 };
-    FIELD1
-}
-
-const fn read_field2() -> Field2 {
-    const FIELD2: Field2 = unsafe { UNION.field2 };
-    FIELD2
-}
-
-const fn read_field3() -> Field3 {
-    const FIELD3: Field3 = unsafe { UNION.field3 };
-    FIELD3
-}
-
-fn main() {
-    assert_eq!(read_field1(), FLOAT1_AS_I32);
-    assert_eq!(read_field2(), 1.0);
-    assert_eq!(read_field3(), unsafe { UNION.field3 });
-}
diff --git a/src/test/run-pass/futures-api.rs b/src/test/run-pass/futures-api.rs
new file mode 100644
index 0000000..3b5a172
--- /dev/null
+++ b/src/test/run-pass/futures-api.rs
@@ -0,0 +1,95 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(arbitrary_self_types, futures_api, pin)]
+#![allow(unused)]
+
+use std::boxed::PinBox;
+use std::future::Future;
+use std::mem::PinMut;
+use std::rc::Rc;
+use std::sync::{
+    Arc,
+    atomic::{self, AtomicUsize},
+};
+use std::task::{
+    Context, Poll,
+    Wake, Waker, LocalWaker,
+    Executor, TaskObj, SpawnObjError,
+    local_waker, local_waker_from_nonlocal,
+};
+
+struct Counter {
+    local_wakes: AtomicUsize,
+    nonlocal_wakes: AtomicUsize,
+}
+
+impl Wake for Counter {
+    fn wake(this: &Arc<Self>) {
+        this.nonlocal_wakes.fetch_add(1, atomic::Ordering::SeqCst);
+    }
+
+    unsafe fn wake_local(this: &Arc<Self>) {
+        this.local_wakes.fetch_add(1, atomic::Ordering::SeqCst);
+    }
+}
+
+struct NoopExecutor;
+
+impl Executor for NoopExecutor {
+    fn spawn_obj(&mut self, _: TaskObj) -> Result<(), SpawnObjError> {
+        Ok(())
+    }
+}
+
+struct MyFuture;
+
+impl Future for MyFuture {
+    type Output = ();
+    fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
+        // Ensure all the methods work appropriately
+        cx.waker().wake();
+        cx.waker().wake();
+        cx.local_waker().wake();
+        cx.executor().spawn_obj(PinBox::new(MyFuture).into()).unwrap();
+        Poll::Ready(())
+    }
+}
+
+fn test_local_waker() {
+    let counter = Arc::new(Counter {
+        local_wakes: AtomicUsize::new(0),
+        nonlocal_wakes: AtomicUsize::new(0),
+    });
+    let waker = unsafe { local_waker(counter.clone()) };
+    let executor = &mut NoopExecutor;
+    let cx = &mut Context::new(&waker, executor);
+    assert_eq!(Poll::Ready(()), PinMut::new(&mut MyFuture).poll(cx));
+    assert_eq!(1, counter.local_wakes.load(atomic::Ordering::SeqCst));
+    assert_eq!(2, counter.nonlocal_wakes.load(atomic::Ordering::SeqCst));
+}
+
+fn test_local_as_nonlocal_waker() {
+    let counter = Arc::new(Counter {
+        local_wakes: AtomicUsize::new(0),
+        nonlocal_wakes: AtomicUsize::new(0),
+    });
+    let waker: LocalWaker = local_waker_from_nonlocal(counter.clone());
+    let executor = &mut NoopExecutor;
+    let cx = &mut Context::new(&waker, executor);
+    assert_eq!(Poll::Ready(()), PinMut::new(&mut MyFuture).poll(cx));
+    assert_eq!(0, counter.local_wakes.load(atomic::Ordering::SeqCst));
+    assert_eq!(3, counter.nonlocal_wakes.load(atomic::Ordering::SeqCst));
+}
+
+fn main() {
+    test_local_waker();
+    test_local_as_nonlocal_waker();
+}
diff --git a/src/test/run-pass/impl-trait/auxiliary/xcrate.rs b/src/test/run-pass/impl-trait/auxiliary/xcrate.rs
index c27a2dd..6e2944e 100644
--- a/src/test/run-pass/impl-trait/auxiliary/xcrate.rs
+++ b/src/test/run-pass/impl-trait/auxiliary/xcrate.rs
@@ -23,3 +23,7 @@
         some_internal_fn() + 1
     }
 }
+
+pub fn return_internal_fn() -> impl Fn() -> u32 {
+    some_internal_fn
+}
diff --git a/src/test/run-pass/impl-trait/bounds_regression.rs b/src/test/run-pass/impl-trait/bounds_regression.rs
new file mode 100644
index 0000000..cc931a6
--- /dev/null
+++ b/src/test/run-pass/impl-trait/bounds_regression.rs
@@ -0,0 +1,32 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub trait FakeGenerator {
+    type Yield;
+    type Return;
+}
+
+pub trait FakeFuture {
+    type Output;
+}
+
+pub fn future_from_generator<
+    T: FakeGenerator<Yield = ()>
+>(x: T) -> impl FakeFuture<Output = T::Return> {
+    GenFuture(x)
+}
+
+struct GenFuture<T: FakeGenerator<Yield = ()>>(T);
+
+impl<T: FakeGenerator<Yield = ()>> FakeFuture for GenFuture<T> {
+    type Output = T::Return;
+}
+
+fn main() {}
diff --git a/src/test/run-pass/impl-trait/example-calendar.rs b/src/test/run-pass/impl-trait/example-calendar.rs
index e3b7322..fce3125 100644
--- a/src/test/run-pass/impl-trait/example-calendar.rs
+++ b/src/test/run-pass/impl-trait/example-calendar.rs
@@ -14,8 +14,6 @@
 #![feature(fn_traits,
            step_trait,
            unboxed_closures,
-           copy_closures,
-           clone_closures
 )]
 
 //! Derived from: <https://raw.githubusercontent.com/quickfur/dcal/master/dcal.d>.
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/run-pass/impl-trait/existential-minimal.rs
similarity index 90%
rename from src/test/ui/const-eval/index_out_of_bound.rs
rename to src/test/run-pass/impl-trait/existential-minimal.rs
index e7ffbe8..4e9d786 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/run-pass/impl-trait/existential-minimal.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
-
 fn main() {}
+
+fn foo() -> impl std::fmt::Debug { "cake" }
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/run-pass/impl-trait/nesting.rs
similarity index 65%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/run-pass/impl-trait/nesting.rs
index e7ffbe8..73e6c1c 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/run-pass/impl-trait/nesting.rs
@@ -8,7 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
+fn foo<T>(t: T) -> impl Into<[T; { const FOO: usize = 1; FOO }]> {
+    [t]
+}
 
-fn main() {}
+fn bar() -> impl Into<[u8; { const FOO: usize = 1; FOO }]> {
+    [99]
+}
+
+fn main() {
+    println!("{:?}", foo(42).into());
+    println!("{:?}", bar().into());
+}
diff --git a/src/test/ui/feature-gate-global_allocator.rs b/src/test/run-pass/impl-trait/xcrate_simple.rs
similarity index 81%
rename from src/test/ui/feature-gate-global_allocator.rs
rename to src/test/run-pass/impl-trait/xcrate_simple.rs
index ff3c342..8d4086c 100644
--- a/src/test/ui/feature-gate-global_allocator.rs
+++ b/src/test/run-pass/impl-trait/xcrate_simple.rs
@@ -8,7 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[global_allocator] //~ ERROR: attribute is an experimental feature
-static A: usize = 0;
+// aux-build:xcrate.rs
 
-fn main() {}
+extern crate xcrate;
+
+fn main() {
+    xcrate::return_internal_fn()();
+}
diff --git a/src/test/run-pass/issue-51582.rs b/src/test/run-pass/issue-51582.rs
new file mode 100644
index 0000000..bca05d8
--- /dev/null
+++ b/src/test/run-pass/issue-51582.rs
@@ -0,0 +1,27 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(core_intrinsics)]
+
+#[repr(i8)]
+pub enum Enum {
+    VariantA,
+    VariantB,
+}
+
+fn make_b() -> Enum { Enum::VariantB }
+
+fn main() {
+    assert_eq!(1, make_b() as i8);
+    assert_eq!(1, make_b() as u8);
+    assert_eq!(1, make_b() as i32);
+    assert_eq!(1, make_b() as u32);
+    assert_eq!(1, unsafe { std::intrinsics::discriminant_value(&make_b()) });
+}
diff --git a/src/test/run-pass/macro-at-most-once-rep.rs b/src/test/run-pass/macro-at-most-once-rep.rs
index c08effe..b7e942f 100644
--- a/src/test/run-pass/macro-at-most-once-rep.rs
+++ b/src/test/run-pass/macro-at-most-once-rep.rs
@@ -32,13 +32,25 @@
     } }
 }
 
+macro_rules! baz {
+    ($($a:ident),? ; $num:expr) => { { // comma separator is meaningless for `?`
+        let mut x = 0;
+
+        $(
+            x += $a;
+         )?
+
+        assert_eq!(x, $num);
+    } }
+}
+
 macro_rules! barplus {
     ($($a:ident)?+ ; $num:expr) => { {
         let mut x = 0;
 
         $(
             x += $a;
-         )?
+         )+
 
         assert_eq!(x, $num);
     } }
@@ -50,7 +62,7 @@
 
         $(
             x += $a;
-         )?
+         )*
 
         assert_eq!(x, $num);
     } }
@@ -62,10 +74,15 @@
     // accept 0 or 1 repetitions
     foo!( ; 0);
     foo!(a ; 1);
+    baz!( ; 0);
+    baz!(a ; 1);
 
     // Make sure using ? as a separator works as before
-    barplus!(+ ; 0);
-    barplus!(a + ; 1);
-    barstar!(* ; 0);
-    barstar!(a * ; 1);
+    barplus!(a ; 1);
+    barplus!(a?a ; 2);
+    barplus!(a?a?a ; 3);
+    barstar!( ; 0);
+    barstar!(a ; 1);
+    barstar!(a?a ; 2);
+    barstar!(a?a?a ; 3);
 }
diff --git a/src/test/run-pass/macro-first-set.rs b/src/test/run-pass/macro-first-set.rs
index 99e5d22..c371a33 100644
--- a/src/test/run-pass/macro-first-set.rs
+++ b/src/test/run-pass/macro-first-set.rs
@@ -199,6 +199,40 @@
 
 //}}}
 
+//{{{ issue 50903 ==============================================================
+
+macro_rules! foo_50903 {
+    ($($lif:lifetime ,)* #) => {};
+}
+
+foo_50903!('a, 'b, #);
+foo_50903!('a, #);
+foo_50903!(#);
+
+//}}}
+
+//{{{ issue 51477 ==============================================================
+
+macro_rules! foo_51477 {
+    ($lifetime:lifetime) => {
+        "last token is lifetime"
+    };
+    ($other:tt) => {
+        "last token is other"
+    };
+    ($first:tt $($rest:tt)*) => {
+        foo_51477!($($rest)*)
+    };
+}
+
+fn test_51477() {
+    assert_eq!("last token is lifetime", foo_51477!('a));
+    assert_eq!("last token is other", foo_51477!(@));
+    assert_eq!("last token is lifetime", foo_51477!(@ {} 'a));
+}
+
+//}}}
+
 //{{{ some more tests ==========================================================
 
 macro_rules! test_block {
@@ -234,6 +268,14 @@
 
 test_meta_block!(windows {});
 
+macro_rules! test_lifetime {
+    (1. $($l:lifetime)* $($b:block)*) => {};
+    (2. $($b:block)* $($l:lifetime)*) => {};
+}
+
+test_lifetime!(1. 'a 'b {} {});
+test_lifetime!(2. {} {} 'a 'b);
+
 //}}}
 
 fn main() {
@@ -241,5 +283,6 @@
     test_40569();
     test_35650();
     test_24189();
+    test_51477();
 }
 
diff --git a/src/test/run-pass/mod_dir_path.rs b/src/test/run-pass/mod_dir_path.rs
index e2f3396..fc91ea8 100644
--- a/src/test/run-pass/mod_dir_path.rs
+++ b/src/test/run-pass/mod_dir_path.rs
@@ -20,12 +20,12 @@
 
     #[path = "auxiliary"]
     mod foo {
-        mod two_macros;
+        mod two_macros_2;
     }
 
     #[path = "auxiliary"]
     mod bar {
-        macro_rules! m { () => { mod two_macros; } }
+        macro_rules! m { () => { mod two_macros_2; } }
         m!();
     }
 }
diff --git a/src/test/run-pass/range_inclusive.rs b/src/test/run-pass/range_inclusive.rs
index 5d46bfa..b08d16e 100644
--- a/src/test/run-pass/range_inclusive.rs
+++ b/src/test/run-pass/range_inclusive.rs
@@ -10,8 +10,6 @@
 
 // Test inclusive range syntax.
 
-#![feature(iterator_step_by)]
-
 use std::ops::{RangeInclusive, RangeToInclusive};
 
 fn foo() -> isize { 42 }
diff --git a/src/test/run-pass/realloc-16687.rs b/src/test/run-pass/realloc-16687.rs
index febd249..7152e72 100644
--- a/src/test/run-pass/realloc-16687.rs
+++ b/src/test/run-pass/realloc-16687.rs
@@ -64,7 +64,7 @@
             println!("deallocate({:?}, {:?}", ptr, layout);
         }
 
-        Global.dealloc(NonNull::new_unchecked(ptr).as_opaque(), layout);
+        Global.dealloc(NonNull::new_unchecked(ptr), layout);
     }
 
     unsafe fn reallocate(ptr: *mut u8, old: Layout, new: Layout) -> *mut u8 {
@@ -72,7 +72,7 @@
             println!("reallocate({:?}, old={:?}, new={:?})", ptr, old, new);
         }
 
-        let ret = Global.realloc(NonNull::new_unchecked(ptr).as_opaque(), old, new.size())
+        let ret = Global.realloc(NonNull::new_unchecked(ptr), old, new.size())
             .unwrap_or_else(|_| oom(Layout::from_size_align_unchecked(new.size(), old.align())));
 
         if PRINT {
diff --git a/src/test/run-pass/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs b/src/test/run-pass/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs
new file mode 100644
index 0000000..7d8050a
--- /dev/null
+++ b/src/test/run-pass/rfc-2421-unreserve-pure-offsetof-sizeof-alignof.rs
@@ -0,0 +1,22 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that removed keywords are allowed as identifiers.
+fn main () {
+    let offsetof = ();
+    let alignof = ();
+    let sizeof = ();
+    let pure = ();
+}
+
+fn offsetof() {}
+fn alignof() {}
+fn sizeof() {}
+fn pure() {}
diff --git a/src/test/run-pass/stack-probes-lto.rs b/src/test/run-pass/stack-probes-lto.rs
index d1cb759..3fef19c 100644
--- a/src/test/run-pass/stack-probes-lto.rs
+++ b/src/test/run-pass/stack-probes-lto.rs
@@ -14,6 +14,8 @@
 // ignore-mips64
 // ignore-powerpc
 // ignore-s390x
+// ignore-sparc
+// ignore-sparc64
 // ignore-wasm
 // ignore-cloudabi no processes
 // ignore-emscripten no processes
diff --git a/src/test/run-pass/stack-probes.rs b/src/test/run-pass/stack-probes.rs
index 78c5782..c93dcf0 100644
--- a/src/test/run-pass/stack-probes.rs
+++ b/src/test/run-pass/stack-probes.rs
@@ -14,6 +14,8 @@
 // ignore-mips64
 // ignore-powerpc
 // ignore-s390x
+// ignore-sparc
+// ignore-sparc64
 // ignore-wasm
 // ignore-cloudabi no processes
 // ignore-emscripten no processes
diff --git a/src/test/run-pass/sync-send-iterators-in-libcore.rs b/src/test/run-pass/sync-send-iterators-in-libcore.rs
index c11a0d3..bb19054 100644
--- a/src/test/run-pass/sync-send-iterators-in-libcore.rs
+++ b/src/test/run-pass/sync-send-iterators-in-libcore.rs
@@ -14,7 +14,6 @@
 #![feature(iter_empty)]
 #![feature(iter_once)]
 #![feature(iter_unfold)]
-#![feature(iterator_step_by)]
 #![feature(str_escape)]
 
 use std::iter::{empty, once, repeat};
diff --git a/src/test/run-pass/thin-lto-global-allocator.rs b/src/test/run-pass/thin-lto-global-allocator.rs
index a0534ff..3a0e2fe 100644
--- a/src/test/run-pass/thin-lto-global-allocator.rs
+++ b/src/test/run-pass/thin-lto-global-allocator.rs
@@ -11,8 +11,6 @@
 // compile-flags: -Z thinlto -C codegen-units=2
 // min-llvm-version 4.0
 
-#![feature(allocator_api, global_allocator)]
-
 #[global_allocator]
 static A: std::alloc::System = std::alloc::System;
 
diff --git a/src/test/run-pass/trait-object-auto-dedup.rs b/src/test/run-pass/trait-object-auto-dedup.rs
new file mode 100644
index 0000000..9f5845f
--- /dev/null
+++ b/src/test/run-pass/trait-object-auto-dedup.rs
@@ -0,0 +1,53 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that duplicate auto trait bounds in trait objects don't create new types.
+#[allow(unused_assignments)]
+
+use std::marker::Send as SendAlias;
+
+// A dummy trait for the non-auto trait.
+trait Trait {}
+
+// A dummy struct to implement Trait, Send, and .
+struct Struct;
+
+impl Trait for Struct {}
+
+// These three functions should be equivalent.
+fn takes_dyn_trait_send(_: Box<dyn Trait + Send>) {}
+fn takes_dyn_trait_send_send(_: Box<dyn Trait + Send + Send>) {}
+fn takes_dyn_trait_send_sendalias(_: Box<dyn Trait + Send + SendAlias>) {}
+
+impl dyn Trait + Send + Send {
+    fn do_nothing(&self) {}
+}
+
+fn main() {
+    // 1. Moving into a variable with more Sends and back.
+    let mut dyn_trait_send = Box::new(Struct) as Box<dyn Trait + Send>;
+    let dyn_trait_send_send: Box<dyn Trait + Send + Send> = dyn_trait_send;
+    dyn_trait_send = dyn_trait_send_send;
+
+    // 2. Calling methods with different number of Sends.
+    let dyn_trait_send = Box::new(Struct) as Box<dyn Trait + Send>;
+    takes_dyn_trait_send_send(dyn_trait_send);
+
+    let dyn_trait_send_send = Box::new(Struct) as Box<dyn Trait + Send + Send>;
+    takes_dyn_trait_send(dyn_trait_send_send);
+
+    // 3. Aliases to the trait are transparent.
+    let dyn_trait_send = Box::new(Struct) as Box<dyn Trait + Send>;
+    takes_dyn_trait_send_sendalias(dyn_trait_send);
+
+    // 4. Calling an impl that duplicates an auto trait.
+    let dyn_trait_send = Box::new(Struct) as Box<dyn Trait + Send>;
+    dyn_trait_send.do_nothing();
+}
diff --git a/src/test/run-pass/union/union-const-eval-field.rs b/src/test/run-pass/union/union-const-eval-field.rs
index f83f49f..a380b01 100644
--- a/src/test/run-pass/union/union-const-eval-field.rs
+++ b/src/test/run-pass/union/union-const-eval-field.rs
@@ -10,7 +10,7 @@
 
 #![feature(const_fn)]
 
-type Field1 = i32;
+type Field1 = (i32, u32);
 type Field2 = f32;
 type Field3 = i64;
 
@@ -21,7 +21,7 @@
 }
 
 const FLOAT1_AS_I32: i32 = 1065353216;
-const UNION: DummyUnion = DummyUnion { field1: FLOAT1_AS_I32 };
+const UNION: DummyUnion = DummyUnion { field1: (FLOAT1_AS_I32, 0) };
 
 const fn read_field1() -> Field1 {
     const FIELD1: Field1 = unsafe { UNION.field1 };
@@ -39,7 +39,15 @@
 }
 
 fn main() {
-    assert_eq!(read_field1(), FLOAT1_AS_I32);
+    let foo = FLOAT1_AS_I32;
+    assert_eq!(read_field1().0, foo);
+    assert_eq!(read_field1().0, FLOAT1_AS_I32);
+
+    let foo = 1.0;
+    assert_eq!(read_field2(), foo);
     assert_eq!(read_field2(), 1.0);
+
     assert_eq!(read_field3(), unsafe { UNION.field3 });
+    let foo = unsafe { UNION.field3 };
+    assert_eq!(read_field3(), foo);
 }
diff --git a/src/test/run-pass/weird-exprs.rs b/src/test/run-pass/weird-exprs.rs
index 37ab2ea..a15fbf3 100644
--- a/src/test/run-pass/weird-exprs.rs
+++ b/src/test/run-pass/weird-exprs.rs
@@ -84,23 +84,26 @@
                                .. .. .. .. .. .. .. .. .. .. .. ..));
 }
 
-fn you_eight() {
-    assert_eq!(8, {
-        macro_rules! u8 {
-            (u8) => {
-                mod u8 {
-                    pub fn u8<'u8>(u8: &'u8 u8) -> &'u8 u8 {
-                        "u8";
-                        u8
+fn u8(u8: u8) {
+    if u8 != 0u8 {
+        assert_eq!(8u8, {
+            macro_rules! u8 {
+                (u8) => {
+                    mod u8 {
+                        pub fn u8<'u8: 'u8 + 'u8>(u8: &'u8 u8) -> &'u8 u8 {
+                            "u8";
+                            u8
+                        }
                     }
-                }
-            };
-        }
+                };
+            }
 
-        u8!(u8);
-        let &u8: &u8 = u8::u8(&8u8);
-        u8
-    });
+            u8!(u8);
+            let &u8: &u8 = u8::u8(&8u8);
+            ::u8(0u8);
+            u8
+        });
+    }
 }
 
 fn fishy() {
@@ -128,7 +131,7 @@
     angrydome();
     evil_lincoln();
     dots();
-    you_eight();
+    u8(8u8);
     fishy();
     union();
     special_characters();
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/rustdoc-js/keyword.js
similarity index 66%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/rustdoc-js/keyword.js
index e7ffbe8..65de3a4 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/rustdoc-js/keyword.js
@@ -8,7 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
+// ignore-order
 
-fn main() {}
+const QUERY = 'fn';
+
+const EXPECTED = {
+    'others': [
+        { 'path': 'std', 'name': 'fn', ty: 15 }, // 15 is for primitive types
+        { 'path': 'std', 'name': 'fn', ty: 21 }, // 21 is for keywords
+    ],
+};
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/rustdoc-js/should-fail.js
similarity index 77%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/rustdoc-js/should-fail.js
index e7ffbe8..5e41422 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/rustdoc-js/should-fail.js
@@ -8,7 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
+// should-fail
 
-fn main() {}
+const QUERY = 'fn';
+
+const EXPECTED = {
+    'others': [
+        { 'path': 'std', 'name': 'fn', ty: 14 },
+    ],
+};
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.rs
similarity index 73%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/rustdoc-ui/deny-intra-link-resolution-failure.rs
index e7ffbe8..85d19c8 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.rs
@@ -1,4 +1,4 @@
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
+#![deny(intra_doc_link_resolution_failure)]
 
-fn main() {}
+/// [v2] //~ ERROR
+pub fn foo() {}
diff --git a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr
new file mode 100644
index 0000000..66ee48e
--- /dev/null
+++ b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr
@@ -0,0 +1,13 @@
+error: `[v2]` cannot be resolved, ignoring it...
+  --> $DIR/deny-intra-link-resolution-failure.rs:13:6
+   |
+13 | /// [v2] //~ ERROR
+   |      ^^ cannot be resolved, ignoring
+   |
+note: lint level defined here
+  --> $DIR/deny-intra-link-resolution-failure.rs:11:9
+   |
+11 | #![deny(intra_doc_link_resolution_failure)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+
diff --git a/src/test/rustdoc-ui/intra-links-warning.rs b/src/test/rustdoc-ui/intra-links-warning.rs
index 2a00d31..d6bc275 100644
--- a/src/test/rustdoc-ui/intra-links-warning.rs
+++ b/src/test/rustdoc-ui/intra-links-warning.rs
@@ -10,8 +10,48 @@
 
 // compile-pass
 
-//! Test with [Foo::baz], [Bar::foo], [Uniooon::X]
+       //! Test with [Foo::baz], [Bar::foo], ...
+     //! , [Uniooon::X] and [Qux::Z].
+       //!
+      //! , [Uniooon::X] and [Qux::Z].
 
+       /// [Qux:Y]
 pub struct Foo {
     pub bar: usize,
 }
+
+/// Foo
+/// bar [BarA] bar
+/// baz
+pub fn a() {}
+
+/**
+ * Foo
+ * bar [BarB] bar
+ * baz
+ */
+pub fn b() {}
+
+/** Foo
+
+bar [BarC] bar
+baz
+
+    let bar_c_1 = 0;
+    let bar_c_2 = 0;
+    let g = [bar_c_1];
+    let h = g[bar_c_2];
+
+*/
+pub fn c() {}
+
+#[doc = "Foo\nbar [BarD] bar\nbaz"]
+pub fn d() {}
+
+macro_rules! f {
+    ($f:expr) => {
+        #[doc = $f]
+        pub fn f() {}
+    }
+}
+f!("Foo\nbar [BarF] bar\nbaz");
diff --git a/src/test/rustdoc-ui/intra-links-warning.stderr b/src/test/rustdoc-ui/intra-links-warning.stderr
index 67d7bdd..2a51e94 100644
--- a/src/test/rustdoc-ui/intra-links-warning.stderr
+++ b/src/test/rustdoc-ui/intra-links-warning.stderr
@@ -1,6 +1,126 @@
-warning: [Foo::baz] cannot be resolved, ignoring it...
+warning: `[Foo::baz]` cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning.rs:13:23
+   |
+13 |        //! Test with [Foo::baz], [Bar::foo], ...
+   |                       ^^^^^^^^ cannot be resolved, ignoring
+   |
+   = note: #[warn(intra_doc_link_resolution_failure)] on by default
+   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
 
-warning: [Bar::foo] cannot be resolved, ignoring it...
+warning: `[Bar::foo]` cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning.rs:13:35
+   |
+13 |        //! Test with [Foo::baz], [Bar::foo], ...
+   |                                   ^^^^^^^^ cannot be resolved, ignoring
+   |
+   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
 
-warning: [Uniooon::X] cannot be resolved, ignoring it...
+warning: `[Uniooon::X]` cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning.rs:14:13
+   |
+14 |      //! , [Uniooon::X] and [Qux::Z].
+   |             ^^^^^^^^^^ cannot be resolved, ignoring
+   |
+   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+
+warning: `[Qux::Z]` cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning.rs:14:30
+   |
+14 |      //! , [Uniooon::X] and [Qux::Z].
+   |                              ^^^^^^ cannot be resolved, ignoring
+   |
+   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+
+warning: `[Uniooon::X]` cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning.rs:16:14
+   |
+16 |       //! , [Uniooon::X] and [Qux::Z].
+   |              ^^^^^^^^^^ cannot be resolved, ignoring
+   |
+   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+
+warning: `[Qux::Z]` cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning.rs:16:31
+   |
+16 |       //! , [Uniooon::X] and [Qux::Z].
+   |                               ^^^^^^ cannot be resolved, ignoring
+   |
+   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+
+warning: `[Qux:Y]` cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning.rs:18:13
+   |
+18 |        /// [Qux:Y]
+   |             ^^^^^ cannot be resolved, ignoring
+   |
+   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+
+warning: `[BarA]` cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning.rs:24:10
+   |
+24 | /// bar [BarA] bar
+   |          ^^^^ cannot be resolved, ignoring
+   |
+   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+
+warning: `[BarB]` cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning.rs:28:1
+   |
+28 | / /**
+29 | |  * Foo
+30 | |  * bar [BarB] bar
+31 | |  * baz
+32 | |  */
+   | |___^
+   |
+   = note: the link appears in this line:
+           
+            bar [BarB] bar
+                 ^^^^
+   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+
+warning: `[BarC]` cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning.rs:35:1
+   |
+35 | / /** Foo
+36 | |
+37 | | bar [BarC] bar
+38 | | baz
+...  |
+44 | |
+45 | | */
+   | |__^
+   |
+   = note: the link appears in this line:
+           
+           bar [BarC] bar
+                ^^^^
+   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+
+warning: `[BarD]` cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning.rs:48:1
+   |
+48 | #[doc = "Foo/nbar [BarD] bar/nbaz"]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the link appears in this line:
+           
+           bar [BarD] bar
+                ^^^^
+   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+
+warning: `[BarF]` cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning.rs:53:9
+   |
+53 |         #[doc = $f]
+   |         ^^^^^^^^^^^
+...
+57 | f!("Foo/nbar [BarF] bar/nbaz");
+   | ------------------------------- in this macro invocation
+   |
+   = note: the link appears in this line:
+           
+           bar [BarF] bar
+                ^^^^
+   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
 
diff --git a/src/test/rustdoc/cap-lints.rs b/src/test/rustdoc/cap-lints.rs
index e7f308a..39e753d 100644
--- a/src/test/rustdoc/cap-lints.rs
+++ b/src/test/rustdoc/cap-lints.rs
@@ -13,8 +13,8 @@
 // therefore should not concern itself with the lints.
 #[deny(warnings)]
 
-// @has cap_lints/struct.foo.html //pre '#[must_use]'
+// @has cap_lints/struct.Foo.html //pre '#[must_use]'
 #[must_use]
-pub struct foo {
+pub struct Foo {
     field: i32,
 }
diff --git a/src/test/ui/feature-gate-global_allocator.rs b/src/test/rustdoc/inline_cross/auxiliary/cross-glob.rs
similarity index 81%
copy from src/test/ui/feature-gate-global_allocator.rs
copy to src/test/rustdoc/inline_cross/auxiliary/cross-glob.rs
index ff3c342..5067ce9 100644
--- a/src/test/ui/feature-gate-global_allocator.rs
+++ b/src/test/rustdoc/inline_cross/auxiliary/cross-glob.rs
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[global_allocator] //~ ERROR: attribute is an experimental feature
-static A: usize = 0;
+#![crate_name = "inner"]
 
-fn main() {}
+pub struct SomeStruct;
+
+pub fn some_fn() {}
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/rustdoc/inline_cross/auxiliary/macros.rs
similarity index 64%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/rustdoc/inline_cross/auxiliary/macros.rs
index e7ffbe8..39b52d6 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/rustdoc/inline_cross/auxiliary/macros.rs
@@ -8,7 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
+#![feature(staged_api)]
 
-fn main() {}
+#![stable(feature = "rust1", since = "1.0.0")]
+
+/// docs for my_macro
+#[unstable(feature = "macro_test", issue = "0")]
+#[rustc_deprecated(since = "1.2.3", reason = "text")]
+#[macro_export]
+macro_rules! my_macro {
+    () => ()
+}
diff --git a/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test3.rs b/src/test/rustdoc/inline_cross/cross-glob.rs
similarity index 63%
copy from src/test/compile-fail/privacy/restricted/tuple-struct-fields/test3.rs
copy to src/test/rustdoc/inline_cross/cross-glob.rs
index dd2cb0e..21cf158 100644
--- a/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test3.rs
+++ b/src/test/rustdoc/inline_cross/cross-glob.rs
@@ -8,15 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-macro_rules! define_struct {
-    ($t:ty) => {
-        struct S1(pub($t));
-        struct S2(pub (in foo) ());
-        struct S3(pub($t) ());
-        //~^ ERROR expected `,`, found `(`
-    }
-}
+// aux-build:cross-glob.rs
+// build-aux-docs
+// ignore-cross-compile
 
-mod foo {
-    define_struct! { foo }
-}
+extern crate inner;
+
+// @has cross_glob/struct.SomeStruct.html
+// @has cross_glob/fn.some_fn.html
+// @!has cross_glob/index.html '//code' 'pub use inner::*;'
+#[doc(inline)]
+pub use inner::*;
diff --git a/src/test/rustdoc/inline_cross/macros.rs b/src/test/rustdoc/inline_cross/macros.rs
new file mode 100644
index 0000000..8d2f7d1
--- /dev/null
+++ b/src/test/rustdoc/inline_cross/macros.rs
@@ -0,0 +1,28 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:macros.rs
+// build-aux-docs
+
+#![feature(macro_test)]
+#![feature(use_extern_macros)]
+
+#![crate_name = "foo"]
+
+extern crate macros;
+
+// @has foo/index.html '//*[@class="docblock-short"]' '[Deprecated] [Experimental]'
+
+// @has foo/macro.my_macro.html
+// @has - '//*[@class="docblock"]' 'docs for my_macro'
+// @has - '//*[@class="stab deprecated"]' 'Deprecated since 1.2.3: text'
+// @has - '//*[@class="stab unstable"]' 'macro_test'
+// @has - '//a/@href' '../src/macros/macros.rs.html#19-21'
+pub use macros::my_macro;
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/rustdoc/invalid.crate.name.rs
similarity index 88%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/rustdoc/invalid.crate.name.rs
index e7ffbe8..4e4946a 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/rustdoc/invalid.crate.name.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
+// compile-flags: --crate-name foo
 
-fn main() {}
+pub fn foo() {}
diff --git a/src/test/rustdoc/keyword.rs b/src/test/rustdoc/keyword.rs
new file mode 100644
index 0000000..b255ffd
--- /dev/null
+++ b/src/test/rustdoc/keyword.rs
@@ -0,0 +1,24 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_name = "foo"]
+
+#![feature(doc_keyword)]
+
+// @has foo/index.html '//h2[@id="keywords"]' 'Keywords'
+// @has foo/index.html '//a[@href="keyword.match.html"]' 'match'
+// @has foo/keyword.match.html '//a[@class="keyword"]' 'match'
+// @has foo/keyword.match.html '//section[@id="main"]//div[@class="docblock"]//p' 'this is a test!'
+// @!has foo/index.html '//a/@href' 'foo/index.html'
+// @!has foo/foo/index.html
+// @!has-dir foo/foo
+#[doc(keyword = "match")]
+/// this is a test!
+mod foo{}
diff --git a/src/test/rustdoc/namespaces.rs b/src/test/rustdoc/namespaces.rs
new file mode 100644
index 0000000..ec1bc35
--- /dev/null
+++ b/src/test/rustdoc/namespaces.rs
@@ -0,0 +1,26 @@
+// Copyright 2016 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.
+
+// issue #34843: rustdoc prioritises documenting reexports from the type namespace
+
+mod inner {
+    pub mod sync {
+        pub struct SomeStruct;
+    }
+
+    pub fn sync() {}
+}
+
+// @has namespaces/sync/index.html
+// @has namespaces/fn.sync.html
+// @has namespaces/index.html '//a/@href' 'sync/index.html'
+// @has - '//a/@href' 'fn.sync.html'
+#[doc(inline)]
+pub use inner::sync;
diff --git a/src/test/rustdoc/rustc-macro-crate.rs b/src/test/rustdoc/rustc-macro-crate.rs
index dc28732..d46f968 100644
--- a/src/test/rustdoc/rustc-macro-crate.rs
+++ b/src/test/rustdoc/rustc-macro-crate.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 // no-prefer-dynamic
+// ignore-stage1
 
 #![crate_type = "proc-macro"]
 
diff --git a/src/test/rustdoc/trait-attributes.rs b/src/test/rustdoc/trait-attributes.rs
new file mode 100644
index 0000000..00d1040
--- /dev/null
+++ b/src/test/rustdoc/trait-attributes.rs
@@ -0,0 +1,32 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_name = "foo"]
+
+// ignore-tidy-linelength
+
+pub trait Foo {
+    // @has foo/trait.Foo.html '//h3[@id="tymethod.foo"]//div[@class="docblock attributes"]' '#[must_use]'
+    #[must_use]
+    fn foo();
+}
+
+#[must_use]
+pub struct Bar;
+
+impl Bar {
+    // @has foo/struct.Bar.html '//h4[@id="method.bar"]//div[@class="docblock attributes"]' '#[must_use]'
+    #[must_use]
+    pub fn bar() {}
+
+    // @has foo/struct.Bar.html '//h4[@id="method.bar2"]//div[@class="docblock attributes"]' '#[must_use]'
+    #[must_use]
+    pub fn bar2() {}
+}
diff --git a/src/test/rustfix/update-all-references.sh b/src/test/rustfix/update-all-references.sh
deleted file mode 100755
index c3f6150..0000000
--- a/src/test/rustfix/update-all-references.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-# A script to update the references for all tests. The idea is that
-# you do a run, which will generate files in the build directory
-# containing the (normalized) actual output of the compiler. You then
-# run this script, which will copy those files over. If you find
-# yourself manually editing a foo.stderr file, you're doing it wrong.
-#
-# See all `update-references.sh`, if you just want to update a single test.
-
-if [[ "$1" == "--help" || "$1" == "-h" || "$1" == "" || "$2" != "" ]]; then
-    echo "usage: $0 <build-directory>"
-    echo ""
-    echo "For example:"
-    echo "   $0 ../../../build/x86_64-apple-darwin/test/rustfix"
-fi
-
-BUILD_DIR=$PWD/$1
-MY_DIR=$(dirname $0)
-cd $MY_DIR
-find . -name '*.rs' | xargs ./update-references.sh $BUILD_DIR
diff --git a/src/test/rustfix/update-references.sh b/src/test/rustfix/update-references.sh
deleted file mode 100755
index bcca2fe..0000000
--- a/src/test/rustfix/update-references.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-# A script to update the references for particular tests. The idea is
-# that you do a run, which will generate files in the build directory
-# containing the (normalized) actual output of the compiler. This
-# script will then copy that output and replace the "expected output"
-# files. You can then commit the changes.
-#
-# If you find yourself manually editing a foo.stderr file, you're
-# doing it wrong.
-
-if [[ "$1" == "--help" || "$1" == "-h" || "$1" == "" || "$2" == "" ]]; then
-    echo "usage: $0 <build-directory> <relative-path-to-rs-files>"
-    echo ""
-    echo "For example:"
-    echo "   $0 ../../../build/x86_64-apple-darwin/test/rustfix *.rs */*.rs"
-fi
-
-MYDIR=$(dirname $0)
-
-BUILD_DIR="$1"
-shift
-
-shopt -s nullglob
-
-while [[ "$1" != "" ]]; do
-    for OUT_NAME in $BUILD_DIR/${1%.rs}.*fixed; do
-        OUT_BASE=`basename "$OUT_NAME"`
-        if ! (diff $OUT_NAME $MYDIR/$OUT_BASE >& /dev/null); then
-            echo updating $MYDIR/$OUT_BASE
-            cp $OUT_NAME $MYDIR
-        fi
-    done
-    shift
-done
diff --git a/src/test/ui-fulldeps/unnecessary-extern-crate.rs b/src/test/ui-fulldeps/unnecessary-extern-crate.rs
index fc6cb6b..0811c79 100644
--- a/src/test/ui-fulldeps/unnecessary-extern-crate.rs
+++ b/src/test/ui-fulldeps/unnecessary-extern-crate.rs
@@ -10,48 +10,90 @@
 
 // compile-flags: --edition 2018
 
-#![deny(unnecessary_extern_crates)]
+#![deny(unused_extern_crates)]
 #![feature(alloc, test, libc)]
 
 extern crate alloc;
-//~^ ERROR `extern crate` is unnecessary in the new edition
+//~^ ERROR unused extern crate
 //~| HELP remove
 extern crate alloc as x;
-//~^ ERROR `extern crate` is unnecessary in the new edition
-//~| HELP use `use`
+//~^ ERROR unused extern crate
+//~| HELP remove
 
 #[macro_use]
 extern crate test;
-pub extern crate test as y;
-//~^ ERROR `extern crate` is unnecessary in the new edition
-//~| HELP use `pub use`
-pub extern crate libc;
-//~^ ERROR `extern crate` is unnecessary in the new edition
-//~| HELP use `pub use`
 
+pub extern crate test as y;
+//~^ ERROR `extern crate` is not idiomatic in the new edition
+//~| HELP convert it to a `pub use`
+
+pub extern crate libc;
+//~^ ERROR `extern crate` is not idiomatic in the new edition
+//~| HELP convert it to a `pub use`
+
+pub(crate) extern crate libc as a;
+//~^ ERROR `extern crate` is not idiomatic in the new edition
+//~| HELP convert it to a `pub(crate) use`
+
+crate extern crate libc as b;
+//~^ ERROR `extern crate` is not idiomatic in the new edition
+//~| HELP convert it to a `crate use`
 
 mod foo {
+    pub(in crate::foo) extern crate libc as c;
+    //~^ ERROR `extern crate` is not idiomatic in the new edition
+    //~| HELP convert it to a `pub(in crate::foo) use`
+
+    pub(super) extern crate libc as d;
+    //~^ ERROR `extern crate` is not idiomatic in the new edition
+    //~| HELP convert it to a `pub(super) use`
+
     extern crate alloc;
-    //~^ ERROR `extern crate` is unnecessary in the new edition
-    //~| HELP use `use`
+    //~^ ERROR unused extern crate
+    //~| HELP remove
+
     extern crate alloc as x;
-    //~^ ERROR `extern crate` is unnecessary in the new edition
-    //~| HELP use `use`
+    //~^ ERROR unused extern crate
+    //~| HELP remove
+
     pub extern crate test;
-    //~^ ERROR `extern crate` is unnecessary in the new edition
-    //~| HELP use `pub use`
+    //~^ ERROR `extern crate` is not idiomatic in the new edition
+    //~| HELP convert it
+
     pub extern crate test as y;
-    //~^ ERROR `extern crate` is unnecessary in the new edition
-    //~| HELP use `pub use`
+    //~^ ERROR `extern crate` is not idiomatic in the new edition
+    //~| HELP convert it
+
     mod bar {
         extern crate alloc;
-        //~^ ERROR `extern crate` is unnecessary in the new edition
-        //~| HELP use `use`
+        //~^ ERROR unused extern crate
+        //~| HELP remove
+
         extern crate alloc as x;
-        //~^ ERROR `extern crate` is unnecessary in the new edition
-        //~| HELP use `use`
+        //~^ ERROR unused extern crate
+        //~| HELP remove
+
+        pub(in crate::foo::bar) extern crate libc as e;
+        //~^ ERROR `extern crate` is not idiomatic in the new edition
+        //~| HELP convert it to a `pub(in crate::foo::bar) use`
+
+        fn dummy() {
+            unsafe {
+                e::getpid();
+            }
+        }
+    }
+
+    fn dummy() {
+        unsafe {
+            c::getpid();
+            d::getpid();
+        }
     }
 }
 
 
-fn main() {}
+fn main() {
+    unsafe { a::getpid(); }
+    unsafe { b::getpid(); }
+}
diff --git a/src/test/ui-fulldeps/unnecessary-extern-crate.stderr b/src/test/ui-fulldeps/unnecessary-extern-crate.stderr
index b9ccf5b..a430711 100644
--- a/src/test/ui-fulldeps/unnecessary-extern-crate.stderr
+++ b/src/test/ui-fulldeps/unnecessary-extern-crate.stderr
@@ -1,4 +1,4 @@
-error: `extern crate` is unnecessary in the new edition
+error: unused extern crate
   --> $DIR/unnecessary-extern-crate.rs:16:1
    |
 LL | extern crate alloc;
@@ -7,62 +7,92 @@
 note: lint level defined here
   --> $DIR/unnecessary-extern-crate.rs:13:9
    |
-LL | #![deny(unnecessary_extern_crates)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(unused_extern_crates)]
+   |         ^^^^^^^^^^^^^^^^^^^^
 
-error: `extern crate` is unnecessary in the new edition
+error: unused extern crate
   --> $DIR/unnecessary-extern-crate.rs:19:1
    |
 LL | extern crate alloc as x;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc as x;`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
 
-error: `extern crate` is unnecessary in the new edition
-  --> $DIR/unnecessary-extern-crate.rs:25:1
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:26:1
    |
 LL | pub extern crate test as y;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `pub use`: `pub use test as y;`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub use`
 
-error: `extern crate` is unnecessary in the new edition
-  --> $DIR/unnecessary-extern-crate.rs:28:1
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:30:1
    |
 LL | pub extern crate libc;
-   | ^^^^^^^^^^^^^^^^^^^^^^ help: use `pub use`: `pub use libc;`
+   | ^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub use`
 
-error: `extern crate` is unnecessary in the new edition
-  --> $DIR/unnecessary-extern-crate.rs:34:5
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:34:1
    |
-LL |     extern crate alloc;
-   |     ^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc;`
+LL | pub(crate) extern crate libc as a;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub(crate) use`
 
-error: `extern crate` is unnecessary in the new edition
-  --> $DIR/unnecessary-extern-crate.rs:37:5
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:38:1
    |
-LL |     extern crate alloc as x;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc as x;`
+LL | crate extern crate libc as b;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `crate use`
 
-error: `extern crate` is unnecessary in the new edition
-  --> $DIR/unnecessary-extern-crate.rs:40:5
-   |
-LL |     pub extern crate test;
-   |     ^^^^^^^^^^^^^^^^^^^^^^ help: use `pub use`: `pub use test;`
-
-error: `extern crate` is unnecessary in the new edition
+error: `extern crate` is not idiomatic in the new edition
   --> $DIR/unnecessary-extern-crate.rs:43:5
    |
-LL |     pub extern crate test as y;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `pub use`: `pub use test as y;`
+LL |     pub(in crate::foo) extern crate libc as c;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub(in crate::foo) use`
 
-error: `extern crate` is unnecessary in the new edition
-  --> $DIR/unnecessary-extern-crate.rs:47:9
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:47:5
+   |
+LL |     pub(super) extern crate libc as d;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub(super) use`
+
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:51:5
+   |
+LL |     extern crate alloc;
+   |     ^^^^^^^^^^^^^^^^^^^ help: remove it
+
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:55:5
+   |
+LL |     extern crate alloc as x;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
+
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:59:5
+   |
+LL |     pub extern crate test;
+   |     ^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub use`
+
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:63:5
+   |
+LL |     pub extern crate test as y;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub use`
+
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:68:9
    |
 LL |         extern crate alloc;
-   |         ^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc;`
+   |         ^^^^^^^^^^^^^^^^^^^ help: remove it
 
-error: `extern crate` is unnecessary in the new edition
-  --> $DIR/unnecessary-extern-crate.rs:50:9
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:72:9
    |
 LL |         extern crate alloc as x;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc as x;`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
 
-error: aborting due to 10 previous errors
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:76:9
+   |
+LL |         pub(in crate::foo::bar) extern crate libc as e;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub(in crate::foo::bar) use`
+
+error: aborting due to 15 previous errors
 
diff --git a/src/test/ui-fulldeps/update-all-references.sh b/src/test/ui-fulldeps/update-all-references.sh
deleted file mode 100644
index bfc6f92..0000000
--- a/src/test/ui-fulldeps/update-all-references.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-# A script to update the references for all tests. The idea is that
-# you do a run, which will generate files in the build directory
-# containing the (normalized) actual output of the compiler. You then
-# run this script, which will copy those files over. If you find
-# yourself manually editing a foo.stderr file, you're doing it wrong.
-#
-# See all `update-references.sh`, if you just want to update a single test.
-
-if [[ "$1" == "--help" || "$1" == "-h" || "$1" == "" || "$2" != "" ]]; then
-    echo "usage: $0 <build-directory>"
-    echo ""
-    echo "For example:"
-    echo "   $0 ../../../build/x86_64-apple-darwin/test/ui"
-fi
-
-BUILD_DIR=$PWD/$1
-MY_DIR=$(dirname $0)
-cd $MY_DIR
-find . -name '*.rs' | xargs ./update-references.sh $BUILD_DIR
diff --git a/src/test/ui-fulldeps/update-references.sh b/src/test/ui-fulldeps/update-references.sh
deleted file mode 100755
index 48e7ec8..0000000
--- a/src/test/ui-fulldeps/update-references.sh
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-# A script to update the references for particular tests. The idea is
-# that you do a run, which will generate files in the build directory
-# containing the (normalized) actual output of the compiler. This
-# script will then copy that output and replace the "expected output"
-# files. You can then commit the changes.
-#
-# If you find yourself manually editing a foo.stderr file, you're
-# doing it wrong.
-
-if [[ "$1" == "--help" || "$1" == "-h" || "$1" == "" || "$2" == "" ]]; then
-    echo "usage: $0 <build-directory> <relative-path-to-rs-files>"
-    echo ""
-    echo "For example:"
-    echo "   $0 ../../../build/x86_64-apple-darwin/test/ui *.rs */*.rs"
-fi
-
-MYDIR=$(dirname $0)
-
-BUILD_DIR="$1"
-shift
-
-shopt -s nullglob
-
-while [[ "$1" != "" ]]; do
-    for EXT in "stderr" "stdout"; do
-        for OUT_NAME in $BUILD_DIR/${1%.rs}*/*$EXT; do
-            OUT_DIR=`dirname "$1"`
-            OUT_BASE=`basename "$OUT_NAME"`
-            if ! (diff $OUT_NAME $MYDIR/$OUT_DIR/$OUT_BASE >& /dev/null); then
-                echo updating $MYDIR/$OUT_DIR/$OUT_BASE
-                cp $OUT_NAME $MYDIR/$OUT_DIR
-            fi
-        done
-    done
-    shift
-done
diff --git a/src/test/ui/asm-out-assign-imm.rs b/src/test/ui/asm-out-assign-imm.rs
index 055a169..f5bb07a 100644
--- a/src/test/ui/asm-out-assign-imm.rs
+++ b/src/test/ui/asm-out-assign-imm.rs
@@ -11,7 +11,10 @@
 // ignore-s390x
 // ignore-emscripten
 // ignore-powerpc
+// ignore-powerpc64
+// ignore-powerpc64le
 // ignore-sparc
+// ignore-sparc64
 // ignore-mips
 
 #![feature(asm)]
diff --git a/src/test/ui/asm-out-assign-imm.stderr b/src/test/ui/asm-out-assign-imm.stderr
index d9fd4b2..7075914 100644
--- a/src/test/ui/asm-out-assign-imm.stderr
+++ b/src/test/ui/asm-out-assign-imm.stderr
@@ -1,5 +1,5 @@
 error[E0384]: cannot assign twice to immutable variable `x`
-  --> $DIR/asm-out-assign-imm.rs:30:9
+  --> $DIR/asm-out-assign-imm.rs:33:9
    |
 LL |     x = 1;
    |     ----- first assignment to `x`
diff --git a/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.nll.stderr b/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.nll.stderr
index a430c97..96b376e 100644
--- a/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.nll.stderr
@@ -1,15 +1,15 @@
-error[E0507]: cannot move out of borrowed content
+error[E0508]: cannot move out of type `[Foo]`, a non-copy slice
   --> $DIR/borrowck-move-out-of-vec-tail.rs:30:33
    |
 LL |                 &[Foo { string: a },
-   |                                 ^ cannot move out of borrowed content
+   |                                 ^ cannot move out of here
 
-error[E0507]: cannot move out of borrowed content
+error[E0508]: cannot move out of type `[Foo]`, a non-copy slice
   --> $DIR/borrowck-move-out-of-vec-tail.rs:34:33
    |
 LL |                   Foo { string: b }] => {
-   |                                 ^ cannot move out of borrowed content
+   |                                 ^ cannot move out of here
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0507`.
+For more information about this error, try `rustc --explain E0508`.
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.nll.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.nll.stderr
index d5a66a6..6d28a37 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.nll.stderr
@@ -1,51 +1,76 @@
-error[E0507]: cannot move out of borrowed content
-  --> $DIR/borrowck-vec-pattern-nesting.rs:42:15
+error[E0506]: cannot assign to `vec[..]` because it is borrowed
+  --> $DIR/borrowck-vec-pattern-nesting.rs:20:13
+   |
+LL |         [box ref _a, _, _] => {
+   |              ------ borrow of `vec[..]` occurs here
+LL |         //~^ borrow of `vec[..]` occurs here
+LL |             vec[0] = box 4; //~ ERROR cannot assign
+   |             ^^^^^^ assignment to borrowed `vec[..]` occurs here
+LL |             //~^ assignment to borrowed `vec[..]` occurs here
+LL |             _a.use_ref();
+   |             -- borrow later used here
+
+error[E0506]: cannot assign to `vec[..]` because it is borrowed
+  --> $DIR/borrowck-vec-pattern-nesting.rs:33:13
+   |
+LL |         &mut [ref _b..] => {
+   |               ------ borrow of `vec[..]` occurs here
+LL |         //~^ borrow of `vec[..]` occurs here
+LL |             vec[0] = box 4; //~ ERROR cannot assign
+   |             ^^^^^^ assignment to borrowed `vec[..]` occurs here
+LL |             //~^ assignment to borrowed `vec[..]` occurs here
+LL |             _b.use_ref();
+   |             -- borrow later used here
+
+error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
+  --> $DIR/borrowck-vec-pattern-nesting.rs:44:15
    |
 LL |         &mut [_a, //~ ERROR cannot move out
-   |               ^^ cannot move out of borrowed content
+   |               ^^ cannot move out of here
 
-error[E0507]: cannot move out of borrowed content
-  --> $DIR/borrowck-vec-pattern-nesting.rs:55:13
+error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
+  --> $DIR/borrowck-vec-pattern-nesting.rs:57:13
    |
 LL |     let a = vec[0]; //~ ERROR cannot move out
-   |             ^^^^^^ cannot move out of borrowed content
+   |             ^^^^^^ cannot move out of here
 
-error[E0507]: cannot move out of borrowed content
-  --> $DIR/borrowck-vec-pattern-nesting.rs:65:10
+error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
+  --> $DIR/borrowck-vec-pattern-nesting.rs:67:10
    |
 LL |          _b] => {}
-   |          ^^ cannot move out of borrowed content
+   |          ^^ cannot move out of here
 
-error[E0507]: cannot move out of borrowed content
-  --> $DIR/borrowck-vec-pattern-nesting.rs:68:13
+error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
+  --> $DIR/borrowck-vec-pattern-nesting.rs:70:13
    |
 LL |     let a = vec[0]; //~ ERROR cannot move out
-   |             ^^^^^^ cannot move out of borrowed content
+   |             ^^^^^^ cannot move out of here
 
-error[E0507]: cannot move out of borrowed content
-  --> $DIR/borrowck-vec-pattern-nesting.rs:76:15
+error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
+  --> $DIR/borrowck-vec-pattern-nesting.rs:78:15
    |
 LL |         &mut [_a, _b, _c] => {}  //~ ERROR cannot move out
-   |               ^^ cannot move out of borrowed content
+   |               ^^ cannot move out of here
 
-error[E0507]: cannot move out of borrowed content
-  --> $DIR/borrowck-vec-pattern-nesting.rs:76:19
+error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
+  --> $DIR/borrowck-vec-pattern-nesting.rs:78:19
    |
 LL |         &mut [_a, _b, _c] => {}  //~ ERROR cannot move out
-   |                   ^^ cannot move out of borrowed content
+   |                   ^^ cannot move out of here
 
-error[E0507]: cannot move out of borrowed content
-  --> $DIR/borrowck-vec-pattern-nesting.rs:76:23
+error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
+  --> $DIR/borrowck-vec-pattern-nesting.rs:78:23
    |
 LL |         &mut [_a, _b, _c] => {}  //~ ERROR cannot move out
-   |                       ^^ cannot move out of borrowed content
+   |                       ^^ cannot move out of here
 
-error[E0507]: cannot move out of borrowed content
-  --> $DIR/borrowck-vec-pattern-nesting.rs:80:13
+error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
+  --> $DIR/borrowck-vec-pattern-nesting.rs:82:13
    |
 LL |     let a = vec[0]; //~ ERROR cannot move out
-   |             ^^^^^^ cannot move out of borrowed content
+   |             ^^^^^^ cannot move out of here
 
-error: aborting due to 8 previous errors
+error: aborting due to 10 previous errors
 
-For more information about this error, try `rustc --explain E0507`.
+Some errors occurred: E0506, E0508.
+For more information about an error, try `rustc --explain E0506`.
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs
index 111968e..63dac0a 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs
@@ -19,6 +19,7 @@
         //~^ borrow of `vec[..]` occurs here
             vec[0] = box 4; //~ ERROR cannot assign
             //~^ assignment to borrowed `vec[..]` occurs here
+            _a.use_ref();
         }
     }
 }
@@ -31,6 +32,7 @@
         //~^ borrow of `vec[..]` occurs here
             vec[0] = box 4; //~ ERROR cannot assign
             //~^ assignment to borrowed `vec[..]` occurs here
+            _b.use_ref();
         }
     }
 }
@@ -82,3 +84,6 @@
 }
 
 fn main() {}
+
+trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { }  }
+impl<T> Fake for T { }
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr
index 6673549..a03e1ea 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr
@@ -8,7 +8,7 @@
    |             ^^^^^^^^^^^^^^ assignment to borrowed `vec[..]` occurs here
 
 error[E0506]: cannot assign to `vec[..]` because it is borrowed
-  --> $DIR/borrowck-vec-pattern-nesting.rs:32:13
+  --> $DIR/borrowck-vec-pattern-nesting.rs:33:13
    |
 LL |         &mut [ref _b..] => {
    |               ------ borrow of `vec[..]` occurs here
@@ -17,7 +17,7 @@
    |             ^^^^^^^^^^^^^^ assignment to borrowed `vec[..]` occurs here
 
 error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
-  --> $DIR/borrowck-vec-pattern-nesting.rs:42:14
+  --> $DIR/borrowck-vec-pattern-nesting.rs:44:14
    |
 LL |           &mut [_a, //~ ERROR cannot move out
    |                ^-- hint: to prevent move, use `ref _a` or `ref mut _a`
@@ -30,7 +30,7 @@
    | |_________^ cannot move out of here
 
 error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
-  --> $DIR/borrowck-vec-pattern-nesting.rs:55:13
+  --> $DIR/borrowck-vec-pattern-nesting.rs:57:13
    |
 LL |     let a = vec[0]; //~ ERROR cannot move out
    |             ^^^^^^
@@ -39,7 +39,7 @@
    |             help: consider using a reference instead: `&vec[0]`
 
 error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
-  --> $DIR/borrowck-vec-pattern-nesting.rs:63:14
+  --> $DIR/borrowck-vec-pattern-nesting.rs:65:14
    |
 LL |           &mut [ //~ ERROR cannot move out
    |  ______________^
@@ -50,7 +50,7 @@
    |            hint: to prevent move, use `ref _b` or `ref mut _b`
 
 error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
-  --> $DIR/borrowck-vec-pattern-nesting.rs:68:13
+  --> $DIR/borrowck-vec-pattern-nesting.rs:70:13
    |
 LL |     let a = vec[0]; //~ ERROR cannot move out
    |             ^^^^^^
@@ -59,7 +59,7 @@
    |             help: consider using a reference instead: `&vec[0]`
 
 error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
-  --> $DIR/borrowck-vec-pattern-nesting.rs:76:14
+  --> $DIR/borrowck-vec-pattern-nesting.rs:78:14
    |
 LL |         &mut [_a, _b, _c] => {}  //~ ERROR cannot move out
    |              ^--^^--^^--^
@@ -70,7 +70,7 @@
    |              cannot move out of here
 
 error[E0508]: cannot move out of type `[std::boxed::Box<isize>]`, a non-copy slice
-  --> $DIR/borrowck-vec-pattern-nesting.rs:80:13
+  --> $DIR/borrowck-vec-pattern-nesting.rs:82:13
    |
 LL |     let a = vec[0]; //~ ERROR cannot move out
    |             ^^^^^^
diff --git a/src/test/ui/borrowck/mut-borrow-of-mut-ref.nll.stderr b/src/test/ui/borrowck/mut-borrow-of-mut-ref.nll.stderr
new file mode 100644
index 0000000..f8b84bc
--- /dev/null
+++ b/src/test/ui/borrowck/mut-borrow-of-mut-ref.nll.stderr
@@ -0,0 +1,9 @@
+error[E0596]: cannot borrow immutable item `b` as mutable
+  --> $DIR/mut-borrow-of-mut-ref.rs:18:7
+   |
+LL |     g(&mut b) //~ ERROR cannot borrow
+   |       ^^^^^^ cannot borrow as mutable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/feature-gate-repr_transparent.rs b/src/test/ui/borrowck/mut-borrow-of-mut-ref.rs
similarity index 73%
rename from src/test/ui/feature-gate-repr_transparent.rs
rename to src/test/ui/borrowck/mut-borrow-of-mut-ref.rs
index deadf2e..75b9da5 100644
--- a/src/test/ui/feature-gate-repr_transparent.rs
+++ b/src/test/ui/borrowck/mut-borrow-of-mut-ref.rs
@@ -8,7 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[repr(transparent)] //~ error: the `#[repr(transparent)]` attribute is experimental
-struct Foo(u64);
+// Suggest not mutably borrowing a mutable reference
 
-fn main() {}
+fn main() {
+    f(&mut 0)
+}
+
+fn f(b: &mut i32) {
+    g(&mut b) //~ ERROR cannot borrow
+}
+
+fn g(_: &mut i32) {}
diff --git a/src/test/ui/borrowck/mut-borrow-of-mut-ref.stderr b/src/test/ui/borrowck/mut-borrow-of-mut-ref.stderr
new file mode 100644
index 0000000..885164c
--- /dev/null
+++ b/src/test/ui/borrowck/mut-borrow-of-mut-ref.stderr
@@ -0,0 +1,13 @@
+error[E0596]: cannot borrow immutable argument `b` as mutable
+  --> $DIR/mut-borrow-of-mut-ref.rs:18:12
+   |
+LL |     g(&mut b) //~ ERROR cannot borrow
+   |            ^ cannot borrow mutably
+help: consider removing the `&mut`, as it is an immutable binding to a mutable reference
+   |
+LL |     g(b) //~ ERROR cannot borrow
+   |       ^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.nll.stderr b/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.nll.stderr
new file mode 100644
index 0000000..95acdab
--- /dev/null
+++ b/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.nll.stderr
@@ -0,0 +1,63 @@
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/promote-ref-mut-in-let-issue-46557.rs:15:21
+   |
+LL |   fn gimme_static_mut_let() -> &'static mut u32 {
+   |  _______________________________________________-
+LL | |     let ref mut x = 1234543; //~ ERROR
+   | |                     ^^^^^^^ temporary value does not live long enough
+LL | |     x
+LL | | }
+   | | -
+   | | |
+   | |_temporary value only lives until here
+   |   borrow later used here
+
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/promote-ref-mut-in-let-issue-46557.rs:20:25
+   |
+LL |   fn gimme_static_mut_let_nested() -> &'static mut u32 {
+   |  ______________________________________________________-
+LL | |     let (ref mut x, ) = (1234543, ); //~ ERROR
+   | |                         ^^^^^^^^^^^ temporary value does not live long enough
+LL | |     x
+LL | | }
+   | | -
+   | | |
+   | |_temporary value only lives until here
+   |   borrow later used here
+
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/promote-ref-mut-in-let-issue-46557.rs:25:11
+   |
+LL |     match 1234543 {
+   |           ^^^^^^^ temporary value does not live long enough
+...
+LL | }
+   | - temporary value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/promote-ref-mut-in-let-issue-46557.rs:31:11
+   |
+LL |     match (123443,) {
+   |           ^^^^^^^^^ temporary value does not live long enough
+...
+LL | }
+   | - temporary value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/promote-ref-mut-in-let-issue-46557.rs:37:10
+   |
+LL |     &mut 1234543 //~ ERROR
+   |          ^^^^^^^ temporary value does not live long enough
+LL | }
+   | - temporary value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.rs b/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.rs
new file mode 100644
index 0000000..4c5f458
--- /dev/null
+++ b/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.rs
@@ -0,0 +1,41 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that we fail to promote the constant here which has a `ref
+// mut` borrow.
+
+fn gimme_static_mut_let() -> &'static mut u32 {
+    let ref mut x = 1234543; //~ ERROR
+    x
+}
+
+fn gimme_static_mut_let_nested() -> &'static mut u32 {
+    let (ref mut x, ) = (1234543, ); //~ ERROR
+    x
+}
+
+fn gimme_static_mut_match() -> &'static mut u32 {
+    match 1234543 {
+        ref mut x => x //~ ERROR
+    }
+}
+
+fn gimme_static_mut_match_nested() -> &'static mut u32 {
+    match (123443,) {
+        (ref mut x,) => x, //~ ERROR
+    }
+}
+
+fn gimme_static_mut_ampersand() -> &'static mut u32 {
+    &mut 1234543 //~ ERROR
+}
+
+fn main() {
+}
diff --git a/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.stderr b/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.stderr
new file mode 100644
index 0000000..931eb7d
--- /dev/null
+++ b/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.stderr
@@ -0,0 +1,57 @@
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/promote-ref-mut-in-let-issue-46557.rs:15:9
+   |
+LL |     let ref mut x = 1234543; //~ ERROR
+   |         ^^^^^^^^^ temporary value does not live long enough
+LL |     x
+LL | }
+   | - temporary value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/promote-ref-mut-in-let-issue-46557.rs:20:10
+   |
+LL |     let (ref mut x, ) = (1234543, ); //~ ERROR
+   |          ^^^^^^^^^ borrowed value does not live long enough
+LL |     x
+LL | }
+   | - borrowed value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/promote-ref-mut-in-let-issue-46557.rs:26:9
+   |
+LL |         ref mut x => x //~ ERROR
+   |         ^^^^^^^^^ temporary value does not live long enough
+LL |     }
+LL | }
+   | - temporary value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/promote-ref-mut-in-let-issue-46557.rs:32:10
+   |
+LL |         (ref mut x,) => x, //~ ERROR
+   |          ^^^^^^^^^ borrowed value does not live long enough
+LL |     }
+LL | }
+   | - borrowed value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/promote-ref-mut-in-let-issue-46557.rs:37:10
+   |
+LL |     &mut 1234543 //~ ERROR
+   |          ^^^^^^^ temporary value does not live long enough
+LL | }
+   | - temporary value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/const-eval-overflow-2.rs b/src/test/ui/const-eval-overflow-2.rs
index 63f33ca..ce3d54e 100644
--- a/src/test/ui/const-eval-overflow-2.rs
+++ b/src/test/ui/const-eval-overflow-2.rs
@@ -19,11 +19,11 @@
 
 const NEG_128: i8 = -128;
 const NEG_NEG_128: i8 = -NEG_128;
-//~^ ERROR E0080
 
 fn main() {
     match -128i8 {
         NEG_NEG_128 => println!("A"),
+        //~^ ERROR could not evaluate constant pattern
         _ => println!("B"),
     }
 }
diff --git a/src/test/ui/const-eval-overflow-2.stderr b/src/test/ui/const-eval-overflow-2.stderr
index 9cee718..e99d409 100644
--- a/src/test/ui/const-eval-overflow-2.stderr
+++ b/src/test/ui/const-eval-overflow-2.stderr
@@ -1,12 +1,9 @@
-error[E0080]: constant evaluation error
-  --> $DIR/const-eval-overflow-2.rs:21:25
+error[E0080]: could not evaluate constant pattern
+  --> $DIR/const-eval-overflow-2.rs:25:9
    |
 LL | const NEG_NEG_128: i8 = -NEG_128;
-   |                         ^^^^^^^^ attempt to negate with overflow
-   |
-note: for pattern here
-  --> $DIR/const-eval-overflow-2.rs:26:9
-   |
+   |                         -------- attempt to negate with overflow
+...
 LL |         NEG_NEG_128 => println!("A"),
    |         ^^^^^^^^^^^
 
diff --git a/src/test/ui/const-eval-overflow-4.rs b/src/test/ui/const-eval-overflow-4.rs
index ed14036..9fc31b7 100644
--- a/src/test/ui/const-eval-overflow-4.rs
+++ b/src/test/ui/const-eval-overflow-4.rs
@@ -20,9 +20,9 @@
 use std::{u8, u16, u32, u64, usize};
 
 const A_I8_T
+    //~^ ERROR could not evaluate constant expression
     : [u32; (i8::MAX as i8 + 1i8) as usize]
-    //~^ ERROR E0080
-    //~| ERROR attempt to add with overflow
+    //~^ ERROR attempt to add with overflow
     = [0; (i8::MAX as usize) + 1];
 
 fn main() {
diff --git a/src/test/ui/const-eval-overflow-4.stderr b/src/test/ui/const-eval-overflow-4.stderr
index fc4762f..058c873 100644
--- a/src/test/ui/const-eval-overflow-4.stderr
+++ b/src/test/ui/const-eval-overflow-4.stderr
@@ -1,16 +1,21 @@
 error: attempt to add with overflow
-  --> $DIR/const-eval-overflow-4.rs:23:13
+  --> $DIR/const-eval-overflow-4.rs:24:13
    |
 LL |     : [u32; (i8::MAX as i8 + 1i8) as usize]
    |             ^^^^^^^^^^^^^^^^^^^^^
    |
    = note: #[deny(const_err)] on by default
 
-error[E0080]: constant evaluation error
-  --> $DIR/const-eval-overflow-4.rs:23:13
+error[E0080]: could not evaluate constant expression
+  --> $DIR/const-eval-overflow-4.rs:22:1
    |
-LL |     : [u32; (i8::MAX as i8 + 1i8) as usize]
-   |             ^^^^^^^^^^^^^^^^^^^^^ attempt to add with overflow
+LL | / const A_I8_T
+LL | |     //~^ ERROR could not evaluate constant expression
+LL | |     : [u32; (i8::MAX as i8 + 1i8) as usize]
+   | |             --------------------- attempt to add with overflow
+LL | |     //~^ ERROR attempt to add with overflow
+LL | |     = [0; (i8::MAX as usize) + 1];
+   | |__________________________________^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/const-eval/conditional_array_execution.nll.stderr b/src/test/ui/const-eval/conditional_array_execution.nll.stderr
new file mode 100644
index 0000000..3580950
--- /dev/null
+++ b/src/test/ui/const-eval/conditional_array_execution.nll.stderr
@@ -0,0 +1,74 @@
+warning: attempt to subtract with overflow
+  --> $DIR/conditional_array_execution.rs:15:19
+   |
+LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
+   |                   ^^^^^
+   |
+note: lint level defined here
+  --> $DIR/conditional_array_execution.rs:11:9
+   |
+LL | #![warn(const_err)]
+   |         ^^^^^^^^^
+
+warning: this constant cannot be used
+  --> $DIR/conditional_array_execution.rs:15:1
+   |
+LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
+   | ^^^^^^^^^^^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                   |
+   |                   attempt to subtract with overflow
+
+warning: referenced constant
+  --> $DIR/conditional_array_execution.rs:20:20
+   |
+LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
+   |                   ----- attempt to subtract with overflow
+...
+LL |     println!("{}", FOO);
+   |                    ^^^
+
+warning: this expression will panic at runtime
+  --> $DIR/conditional_array_execution.rs:20:20
+   |
+LL |     println!("{}", FOO);
+   |                    ^^^ referenced constant has errors
+
+error[E0080]: referenced constant
+  --> $DIR/conditional_array_execution.rs:20:5
+   |
+LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
+   |                   ----- attempt to subtract with overflow
+...
+LL |     println!("{}", FOO);
+   |     ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error[E0080]: erroneous constant used
+  --> $DIR/conditional_array_execution.rs:20:5
+   |
+LL |     println!("{}", FOO);
+   |     ^^^^^^^^^^^^^^^---^^
+   |                    |
+   |                    referenced constant has errors
+   |
+   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error[E0080]: referenced constant
+  --> $DIR/conditional_array_execution.rs:20:20
+   |
+LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
+   |                   ----- attempt to subtract with overflow
+...
+LL |     println!("{}", FOO);
+   |                    ^^^
+
+error[E0080]: erroneous constant used
+  --> $DIR/conditional_array_execution.rs:20:20
+   |
+LL |     println!("{}", FOO);
+   |                    ^^^ referenced constant has errors
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-eval/conditional_array_execution.rs b/src/test/ui/const-eval/conditional_array_execution.rs
index 8952a83..ac555b2 100644
--- a/src/test/ui/const-eval/conditional_array_execution.rs
+++ b/src/test/ui/const-eval/conditional_array_execution.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-pass
 #![warn(const_err)]
 
 const X: u32 = 5;
@@ -19,5 +18,8 @@
 
 fn main() {
     println!("{}", FOO);
-    //~^ WARN constant evaluation error
+    //~^ WARN this expression will panic at runtime
+    //~| WARN referenced constant
+    //~| ERROR erroneous constant used
+    //~| E0080
 }
diff --git a/src/test/ui/const-eval/conditional_array_execution.stderr b/src/test/ui/const-eval/conditional_array_execution.stderr
index 5cf73b9..64010c9 100644
--- a/src/test/ui/const-eval/conditional_array_execution.stderr
+++ b/src/test/ui/const-eval/conditional_array_execution.stderr
@@ -1,24 +1,53 @@
 warning: attempt to subtract with overflow
-  --> $DIR/conditional_array_execution.rs:16:19
+  --> $DIR/conditional_array_execution.rs:15:19
    |
 LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
    |                   ^^^^^
    |
 note: lint level defined here
-  --> $DIR/conditional_array_execution.rs:12:9
+  --> $DIR/conditional_array_execution.rs:11:9
    |
 LL | #![warn(const_err)]
    |         ^^^^^^^^^
 
 warning: this constant cannot be used
-  --> $DIR/conditional_array_execution.rs:16:1
+  --> $DIR/conditional_array_execution.rs:15:1
    |
 LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
+   | ^^^^^^^^^^^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                   |
+   |                   attempt to subtract with overflow
 
-warning: constant evaluation error
-  --> $DIR/conditional_array_execution.rs:21:20
+warning: referenced constant
+  --> $DIR/conditional_array_execution.rs:20:20
+   |
+LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
+   |                   ----- attempt to subtract with overflow
+...
+LL |     println!("{}", FOO);
+   |                    ^^^
+
+warning: this expression will panic at runtime
+  --> $DIR/conditional_array_execution.rs:20:20
    |
 LL |     println!("{}", FOO);
    |                    ^^^ referenced constant has errors
 
+error[E0080]: referenced constant
+  --> $DIR/conditional_array_execution.rs:20:20
+   |
+LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
+   |                   ----- attempt to subtract with overflow
+...
+LL |     println!("{}", FOO);
+   |                    ^^^
+
+error[E0080]: erroneous constant used
+  --> $DIR/conditional_array_execution.rs:20:20
+   |
+LL |     println!("{}", FOO);
+   |                    ^^^ referenced constant has errors
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-eval/index_out_of_bound.stderr b/src/test/ui/const-eval/index_out_of_bound.stderr
deleted file mode 100644
index d16231c..0000000
--- a/src/test/ui/const-eval/index_out_of_bound.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0080]: constant evaluation error
-  --> $DIR/index_out_of_bound.rs:11:19
-   |
-LL | static FOO: i32 = [][0];
-   |                   ^^^^^ index out of bounds: the len is 0 but the index is 0
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/ui/const-eval/index_out_of_bounds.rs
similarity index 81%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/ui/const-eval/index_out_of_bounds.rs
index e7ffbe8..55c64d2 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/ui/const-eval/index_out_of_bounds.rs
@@ -10,5 +10,9 @@
 
 static FOO: i32 = [][0];
 //~^ ERROR E0080
+//~| ERROR E0080
 
-fn main() {}
+fn main() {
+    let array = [std::env::args().len()];
+    array[1]; //~ ERROR index out of bounds
+}
diff --git a/src/test/ui/const-eval/index_out_of_bounds.stderr b/src/test/ui/const-eval/index_out_of_bounds.stderr
new file mode 100644
index 0000000..828fba5
--- /dev/null
+++ b/src/test/ui/const-eval/index_out_of_bounds.stderr
@@ -0,0 +1,25 @@
+error[E0080]: could not evaluate static initializer
+  --> $DIR/index_out_of_bounds.rs:11:19
+   |
+LL | static FOO: i32 = [][0];
+   |                   ^^^^^ index out of bounds: the len is 0 but the index is 0
+
+error[E0080]: could not evaluate static initializer
+  --> $DIR/index_out_of_bounds.rs:11:1
+   |
+LL | static FOO: i32 = [][0];
+   | ^^^^^^^^^^^^^^^^^^-----^
+   |                   |
+   |                   index out of bounds: the len is 0 but the index is 0
+
+error: index out of bounds: the len is 1 but the index is 1
+  --> $DIR/index_out_of_bounds.rs:17:5
+   |
+LL |     array[1]; //~ ERROR index out of bounds
+   |     ^^^^^^^^
+   |
+   = note: #[deny(const_err)] on by default
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-eval/issue-43197.nll.stderr b/src/test/ui/const-eval/issue-43197.nll.stderr
new file mode 100644
index 0000000..3bde12a
--- /dev/null
+++ b/src/test/ui/const-eval/issue-43197.nll.stderr
@@ -0,0 +1,118 @@
+warning: attempt to subtract with overflow
+  --> $DIR/issue-43197.rs:20:20
+   |
+LL |     const X: u32 = 0-1;
+   |                    ^^^
+   |
+note: lint level defined here
+  --> $DIR/issue-43197.rs:11:9
+   |
+LL | #![warn(const_err)]
+   |         ^^^^^^^^^
+
+warning: this constant cannot be used
+  --> $DIR/issue-43197.rs:20:5
+   |
+LL |     const X: u32 = 0-1;
+   |     ^^^^^^^^^^^^^^^---^
+   |                    |
+   |                    attempt to subtract with overflow
+
+warning: attempt to subtract with overflow
+  --> $DIR/issue-43197.rs:23:24
+   |
+LL |     const Y: u32 = foo(0-1);
+   |                        ^^^
+
+warning: this constant cannot be used
+  --> $DIR/issue-43197.rs:23:5
+   |
+LL |     const Y: u32 = foo(0-1);
+   |     ^^^^^^^^^^^^^^^^^^^---^^
+   |                        |
+   |                        attempt to subtract with overflow
+
+warning: referenced constant
+  --> $DIR/issue-43197.rs:26:23
+   |
+LL |     const X: u32 = 0-1;
+   |                    --- attempt to subtract with overflow
+...
+LL |     println!("{} {}", X, Y);
+   |                       ^
+
+warning: this expression will panic at runtime
+  --> $DIR/issue-43197.rs:26:23
+   |
+LL |     println!("{} {}", X, Y);
+   |                       ^ referenced constant has errors
+
+warning: referenced constant
+  --> $DIR/issue-43197.rs:26:26
+   |
+LL |     const Y: u32 = foo(0-1);
+   |                        --- attempt to subtract with overflow
+...
+LL |     println!("{} {}", X, Y);
+   |                          ^
+
+warning: this expression will panic at runtime
+  --> $DIR/issue-43197.rs:26:26
+   |
+LL |     println!("{} {}", X, Y);
+   |                          ^ referenced constant has errors
+
+error[E0080]: referenced constant
+  --> $DIR/issue-43197.rs:26:5
+   |
+LL |     const X: u32 = 0-1;
+   |                    --- attempt to subtract with overflow
+...
+LL |     println!("{} {}", X, Y);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error[E0080]: erroneous constant used
+  --> $DIR/issue-43197.rs:26:5
+   |
+LL |     println!("{} {}", X, Y);
+   |     ^^^^^^^^^^^^^^^^^^-^^^^^
+   |                       |
+   |                       referenced constant has errors
+   |
+   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error[E0080]: referenced constant
+  --> $DIR/issue-43197.rs:26:26
+   |
+LL |     const Y: u32 = foo(0-1);
+   |                        --- attempt to subtract with overflow
+...
+LL |     println!("{} {}", X, Y);
+   |                          ^
+
+error[E0080]: erroneous constant used
+  --> $DIR/issue-43197.rs:26:26
+   |
+LL |     println!("{} {}", X, Y);
+   |                          ^ referenced constant has errors
+
+error[E0080]: referenced constant
+  --> $DIR/issue-43197.rs:26:23
+   |
+LL |     const X: u32 = 0-1;
+   |                    --- attempt to subtract with overflow
+...
+LL |     println!("{} {}", X, Y);
+   |                       ^
+
+error[E0080]: erroneous constant used
+  --> $DIR/issue-43197.rs:26:23
+   |
+LL |     println!("{} {}", X, Y);
+   |                       ^ referenced constant has errors
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-eval/issue-43197.rs b/src/test/ui/const-eval/issue-43197.rs
index 7ec100e..03aa65e 100644
--- a/src/test/ui/const-eval/issue-43197.rs
+++ b/src/test/ui/const-eval/issue-43197.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-pass
 #![warn(const_err)]
 
 #![feature(const_fn)]
@@ -25,6 +24,12 @@
     //~^ WARN attempt to subtract with overflow
     //~| WARN this constant cannot be used
     println!("{} {}", X, Y);
-    //~^ WARN constant evaluation error
-    //~| WARN constant evaluation error
+    //~^ WARN this expression will panic at runtime
+    //~| WARN this expression will panic at runtime
+    //~| ERROR erroneous constant used
+    //~| ERROR erroneous constant used
+    //~| ERROR E0080
+    //~| ERROR E0080
+    //~| WARN referenced constant
+    //~| WARN referenced constant
 }
diff --git a/src/test/ui/const-eval/issue-43197.stderr b/src/test/ui/const-eval/issue-43197.stderr
index d0e13d5..071d878 100644
--- a/src/test/ui/const-eval/issue-43197.stderr
+++ b/src/test/ui/const-eval/issue-43197.stderr
@@ -1,42 +1,97 @@
 warning: attempt to subtract with overflow
-  --> $DIR/issue-43197.rs:21:20
+  --> $DIR/issue-43197.rs:20:20
    |
 LL |     const X: u32 = 0-1;
    |                    ^^^
    |
 note: lint level defined here
-  --> $DIR/issue-43197.rs:12:9
+  --> $DIR/issue-43197.rs:11:9
    |
 LL | #![warn(const_err)]
    |         ^^^^^^^^^
 
 warning: this constant cannot be used
-  --> $DIR/issue-43197.rs:21:5
+  --> $DIR/issue-43197.rs:20:5
    |
 LL |     const X: u32 = 0-1;
-   |     ^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
+   |     ^^^^^^^^^^^^^^^---^
+   |                    |
+   |                    attempt to subtract with overflow
 
 warning: attempt to subtract with overflow
-  --> $DIR/issue-43197.rs:24:24
+  --> $DIR/issue-43197.rs:23:24
    |
 LL |     const Y: u32 = foo(0-1);
    |                        ^^^
 
 warning: this constant cannot be used
-  --> $DIR/issue-43197.rs:24:5
+  --> $DIR/issue-43197.rs:23:5
    |
 LL |     const Y: u32 = foo(0-1);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
+   |     ^^^^^^^^^^^^^^^^^^^---^^
+   |                        |
+   |                        attempt to subtract with overflow
 
-warning: constant evaluation error
-  --> $DIR/issue-43197.rs:27:23
+warning: referenced constant
+  --> $DIR/issue-43197.rs:26:23
+   |
+LL |     const X: u32 = 0-1;
+   |                    --- attempt to subtract with overflow
+...
+LL |     println!("{} {}", X, Y);
+   |                       ^
+
+warning: this expression will panic at runtime
+  --> $DIR/issue-43197.rs:26:23
    |
 LL |     println!("{} {}", X, Y);
    |                       ^ referenced constant has errors
 
-warning: constant evaluation error
-  --> $DIR/issue-43197.rs:27:26
+warning: referenced constant
+  --> $DIR/issue-43197.rs:26:26
+   |
+LL |     const Y: u32 = foo(0-1);
+   |                        --- attempt to subtract with overflow
+...
+LL |     println!("{} {}", X, Y);
+   |                          ^
+
+warning: this expression will panic at runtime
+  --> $DIR/issue-43197.rs:26:26
    |
 LL |     println!("{} {}", X, Y);
    |                          ^ referenced constant has errors
 
+error[E0080]: referenced constant
+  --> $DIR/issue-43197.rs:26:26
+   |
+LL |     const Y: u32 = foo(0-1);
+   |                        --- attempt to subtract with overflow
+...
+LL |     println!("{} {}", X, Y);
+   |                          ^
+
+error[E0080]: erroneous constant used
+  --> $DIR/issue-43197.rs:26:26
+   |
+LL |     println!("{} {}", X, Y);
+   |                          ^ referenced constant has errors
+
+error[E0080]: referenced constant
+  --> $DIR/issue-43197.rs:26:23
+   |
+LL |     const X: u32 = 0-1;
+   |                    --- attempt to subtract with overflow
+...
+LL |     println!("{} {}", X, Y);
+   |                       ^
+
+error[E0080]: erroneous constant used
+  --> $DIR/issue-43197.rs:26:23
+   |
+LL |     println!("{} {}", X, Y);
+   |                       ^ referenced constant has errors
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-eval/issue-44578.nll.stderr b/src/test/ui/const-eval/issue-44578.nll.stderr
new file mode 100644
index 0000000..ad4f089
--- /dev/null
+++ b/src/test/ui/const-eval/issue-44578.nll.stderr
@@ -0,0 +1,39 @@
+error[E0080]: referenced constant
+  --> $DIR/issue-44578.rs:35:5
+   |
+LL |     const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize];
+   |                        ------------------------------------ index out of bounds: the len is 1 but the index is 1
+...
+LL |     println!("{}", <Bar<u16, u8> as Foo>::AMT);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error[E0080]: erroneous constant used
+  --> $DIR/issue-44578.rs:35:5
+   |
+LL |     println!("{}", <Bar<u16, u8> as Foo>::AMT);
+   |     ^^^^^^^^^^^^^^^--------------------------^^
+   |                    |
+   |                    referenced constant has errors
+   |
+   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error[E0080]: referenced constant
+  --> $DIR/issue-44578.rs:35:20
+   |
+LL |     const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize];
+   |                        ------------------------------------ index out of bounds: the len is 1 but the index is 1
+...
+LL |     println!("{}", <Bar<u16, u8> as Foo>::AMT);
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0080]: erroneous constant used
+  --> $DIR/issue-44578.rs:35:20
+   |
+LL |     println!("{}", <Bar<u16, u8> as Foo>::AMT);
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-eval/issue-44578.rs b/src/test/ui/const-eval/issue-44578.rs
index 4133a88..59ac4ab 100644
--- a/src/test/ui/const-eval/issue-44578.rs
+++ b/src/test/ui/const-eval/issue-44578.rs
@@ -8,8 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-pass
-#![warn(const_err)]
+#![allow(const_err)]
 
 trait Foo {
     const AMT: usize;
@@ -33,6 +32,7 @@
 }
 
 fn main() {
-    println!("{}", <Bar<u16, u8> as Foo>::AMT); //~ WARN const_err
-    //~^ WARN const_err
+    println!("{}", <Bar<u16, u8> as Foo>::AMT);
+    //~^ ERROR erroneous constant used
+    //~| ERROR E0080
 }
diff --git a/src/test/ui/const-eval/issue-44578.stderr b/src/test/ui/const-eval/issue-44578.stderr
index ce6ff86..28a723a 100644
--- a/src/test/ui/const-eval/issue-44578.stderr
+++ b/src/test/ui/const-eval/issue-44578.stderr
@@ -1,18 +1,18 @@
-warning: constant evaluation error
-  --> $DIR/issue-44578.rs:36:20
+error[E0080]: referenced constant
+  --> $DIR/issue-44578.rs:35:20
    |
-LL |     println!("{}", <Bar<u16, u8> as Foo>::AMT); //~ WARN const_err
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
-   |
-note: lint level defined here
-  --> $DIR/issue-44578.rs:12:9
-   |
-LL | #![warn(const_err)]
-   |         ^^^^^^^^^
+LL |     const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize];
+   |                        ------------------------------------ index out of bounds: the len is 1 but the index is 1
+...
+LL |     println!("{}", <Bar<u16, u8> as Foo>::AMT);
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: constant evaluation error
-  --> $DIR/issue-44578.rs:36:20
+error[E0080]: erroneous constant used
+  --> $DIR/issue-44578.rs:35:20
    |
-LL |     println!("{}", <Bar<u16, u8> as Foo>::AMT); //~ WARN const_err
+LL |     println!("{}", <Bar<u16, u8> as Foo>::AMT);
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
 
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-eval/issue-50814-2.rs b/src/test/ui/const-eval/issue-50814-2.rs
new file mode 100644
index 0000000..af627ee
--- /dev/null
+++ b/src/test/ui/const-eval/issue-50814-2.rs
@@ -0,0 +1,43 @@
+// Copyright 2018 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 C {
+    const BOO: usize;
+}
+
+trait Foo<T> {
+    const BAR: usize;
+}
+
+struct A<T>(T);
+
+impl<T: C> Foo<T> for A<T> {
+    const BAR: usize = [5, 6, 7][T::BOO];
+}
+
+fn foo<T: C>() -> &'static usize {
+    &<A<T> as Foo<T>>::BAR //~ ERROR erroneous constant used
+//~| ERROR E0080
+}
+
+impl C for () {
+    const BOO: usize = 42;
+}
+
+impl C for u32 {
+    const BOO: usize = 1;
+}
+
+fn main() {
+    println!("{:x}", foo::<()>() as *const usize as usize);
+    println!("{:x}", foo::<u32>() as *const usize as usize);
+    println!("{:x}", foo::<()>());
+    println!("{:x}", foo::<u32>());
+}
diff --git a/src/test/ui/const-eval/issue-50814-2.stderr b/src/test/ui/const-eval/issue-50814-2.stderr
new file mode 100644
index 0000000..3c59cb0
--- /dev/null
+++ b/src/test/ui/const-eval/issue-50814-2.stderr
@@ -0,0 +1,20 @@
+error[E0080]: referenced constant
+  --> $DIR/issue-50814-2.rs:26:5
+   |
+LL |     const BAR: usize = [5, 6, 7][T::BOO];
+   |                        ----------------- index out of bounds: the len is 3 but the index is 42
+...
+LL |     &<A<T> as Foo<T>>::BAR //~ ERROR erroneous constant used
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0080]: erroneous constant used
+  --> $DIR/issue-50814-2.rs:26:5
+   |
+LL |     &<A<T> as Foo<T>>::BAR //~ ERROR erroneous constant used
+   |     ^---------------------
+   |      |
+   |      referenced constant has errors
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-eval/issue-50814.rs b/src/test/ui/const-eval/issue-50814.rs
new file mode 100644
index 0000000..8f27524
--- /dev/null
+++ b/src/test/ui/const-eval/issue-50814.rs
@@ -0,0 +1,33 @@
+// Copyright 2018 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 Unsigned {
+    const MAX: u8;
+}
+
+struct U8(u8);
+impl Unsigned for U8 {
+    const MAX: u8 = 0xff;
+}
+
+struct Sum<A,B>(A,B);
+
+impl<A: Unsigned, B: Unsigned> Unsigned for Sum<A,B> {
+    const MAX: u8 = A::MAX + B::MAX;
+}
+
+fn foo<T>(_: T) -> &'static u8 {
+    &Sum::<U8,U8>::MAX //~ ERROR erroneous constant used
+//~| ERROR E0080
+}
+
+fn main() {
+    foo(0);
+}
diff --git a/src/test/ui/const-eval/issue-50814.stderr b/src/test/ui/const-eval/issue-50814.stderr
new file mode 100644
index 0000000..145279c
--- /dev/null
+++ b/src/test/ui/const-eval/issue-50814.stderr
@@ -0,0 +1,20 @@
+error[E0080]: referenced constant
+  --> $DIR/issue-50814.rs:27:5
+   |
+LL |     const MAX: u8 = A::MAX + B::MAX;
+   |                     --------------- attempt to add with overflow
+...
+LL |     &Sum::<U8,U8>::MAX //~ ERROR erroneous constant used
+   |     ^^^^^^^^^^^^^^^^^^
+
+error[E0080]: erroneous constant used
+  --> $DIR/issue-50814.rs:27:5
+   |
+LL |     &Sum::<U8,U8>::MAX //~ ERROR erroneous constant used
+   |     ^-----------------
+   |      |
+   |      referenced constant has errors
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-eval/issue-51300.rs b/src/test/ui/const-eval/issue-51300.rs
new file mode 100644
index 0000000..f91711c
--- /dev/null
+++ b/src/test/ui/const-eval/issue-51300.rs
@@ -0,0 +1,41 @@
+// Copyright 2018 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-pass
+// https://github.com/rust-lang/rust/issues/51300
+
+#[derive(PartialEq, Eq, Clone, Copy)]
+pub struct Stat {
+    pub id: u8,
+    pub index: usize,
+}
+
+impl Stat {
+    pub const STUDENT_HAPPINESS: Stat = Stat{
+        id: 0,
+        index: 0,
+    };
+    pub const STUDENT_HUNGER: Stat = Stat{
+        id: 0,
+        index: Self::STUDENT_HAPPINESS.index + 1,
+    };
+
+}
+
+pub fn from_index(id: u8, index: usize) -> Option<Stat> {
+    let stat = Stat{id, index};
+    match stat {
+        Stat::STUDENT_HAPPINESS => Some(Stat::STUDENT_HAPPINESS),
+        Stat::STUDENT_HUNGER => Some(Stat::STUDENT_HUNGER),
+        _ => None,
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/const-eval/promoted_const_fn_fail.rs b/src/test/ui/const-eval/promoted_const_fn_fail.rs
index 5ced2c9..4888ed6 100644
--- a/src/test/ui/const-eval/promoted_const_fn_fail.rs
+++ b/src/test/ui/const-eval/promoted_const_fn_fail.rs
@@ -23,8 +23,8 @@
         // is run on a system whose pointers need more
         // than 8 bits
         Bar { a: &42 }.b as u8
-        //~^ constant evaluation error
-        //~| constant evaluation error
+        //~^ ERROR this expression will panic at runtime
+        //~| ERROR this expression will panic at runtime
     }
 }
 
diff --git a/src/test/ui/const-eval/promoted_const_fn_fail.stderr b/src/test/ui/const-eval/promoted_const_fn_fail.stderr
index f910705..d805e1a 100644
--- a/src/test/ui/const-eval/promoted_const_fn_fail.stderr
+++ b/src/test/ui/const-eval/promoted_const_fn_fail.stderr
@@ -1,4 +1,4 @@
-error: constant evaluation error
+error: this expression will panic at runtime
   --> $DIR/promoted_const_fn_fail.rs:25:9
    |
 LL |         Bar { a: &42 }.b as u8
@@ -9,23 +9,12 @@
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
-note: inside call to `bar`
-  --> $DIR/promoted_const_fn_fail.rs:35:28
-   |
-LL |     let x: &'static u8 = &(bar() + 1);
-   |                            ^^^^^
 
-error: constant evaluation error
+error: this expression will panic at runtime
   --> $DIR/promoted_const_fn_fail.rs:25:9
    |
 LL |         Bar { a: &42 }.b as u8
    |         ^^^^^^^^^^^^^^^^^^^^^^ a raw memory access tried to access part of a pointer value as raw bytes
-   |
-note: inside call to `bar`
-  --> $DIR/promoted_const_fn_fail.rs:35:28
-   |
-LL |     let x: &'static u8 = &(bar() + 1);
-   |                            ^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/const-eval/promoted_errors.stderr b/src/test/ui/const-eval/promoted_errors.stderr
index 683ee53..a4c1c48 100644
--- a/src/test/ui/const-eval/promoted_errors.stderr
+++ b/src/test/ui/const-eval/promoted_errors.stderr
@@ -1,4 +1,4 @@
-warning: constant evaluation error
+warning: this expression will panic at runtime
   --> $DIR/promoted_errors.rs:17:14
    |
 LL |     let _x = 0u32 - 1;
@@ -16,7 +16,7 @@
 LL |     println!("{}", 1/(1-1));
    |                    ^^^^^^^
 
-warning: constant evaluation error
+warning: this expression will panic at runtime
   --> $DIR/promoted_errors.rs:19:20
    |
 LL |     println!("{}", 1/(1-1));
@@ -28,13 +28,13 @@
 LL |     let _x = 1/(1-1);
    |              ^^^^^^^
 
-warning: constant evaluation error
+warning: this expression will panic at runtime
   --> $DIR/promoted_errors.rs:22:14
    |
 LL |     let _x = 1/(1-1);
    |              ^^^^^^^ attempt to divide by zero
 
-warning: constant evaluation error
+warning: this expression will panic at runtime
   --> $DIR/promoted_errors.rs:25:20
    |
 LL |     println!("{}", 1/(false as u32));
diff --git a/src/test/ui/const-eval/pub_const_err.stderr b/src/test/ui/const-eval/pub_const_err.stderr
index 068825f..3522894 100644
--- a/src/test/ui/const-eval/pub_const_err.stderr
+++ b/src/test/ui/const-eval/pub_const_err.stderr
@@ -14,7 +14,9 @@
   --> $DIR/pub_const_err.rs:16:1
    |
 LL | pub const Z: u32 = 0 - 1;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
+   | ^^^^^^^^^^^^^^^^^^^-----^
+   |                    |
+   |                    attempt to subtract with overflow
 
 warning: attempt to subtract with overflow
   --> $DIR/pub_const_err.rs:20:22
diff --git a/src/test/ui/const-eval/pub_const_err_bin.stderr b/src/test/ui/const-eval/pub_const_err_bin.stderr
index dcb8125..a6db217 100644
--- a/src/test/ui/const-eval/pub_const_err_bin.stderr
+++ b/src/test/ui/const-eval/pub_const_err_bin.stderr
@@ -14,7 +14,9 @@
   --> $DIR/pub_const_err_bin.rs:14:1
    |
 LL | pub const Z: u32 = 0 - 1;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
+   | ^^^^^^^^^^^^^^^^^^^-----^
+   |                    |
+   |                    attempt to subtract with overflow
 
 warning: attempt to subtract with overflow
   --> $DIR/pub_const_err_bin.rs:18:22
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/ui/const-eval/union_promotion.rs
similarity index 68%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/ui/const-eval/union_promotion.rs
index e7ffbe8..714d7a4 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/ui/const-eval/union_promotion.rs
@@ -8,7 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
+#![allow(const_err)]
 
-fn main() {}
+union Foo {
+    a: &'static u32,
+    b: usize,
+}
+
+fn main() {
+    let x: &'static bool = &unsafe { //~ borrowed value does not live long enough
+        Foo { a: &1 }.b == Foo { a: &2 }.b
+    };
+}
diff --git a/src/test/ui/const-eval/union_promotion.stderr b/src/test/ui/const-eval/union_promotion.stderr
new file mode 100644
index 0000000..b4aa91f
--- /dev/null
+++ b/src/test/ui/const-eval/union_promotion.stderr
@@ -0,0 +1,16 @@
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/union_promotion.rs:19:29
+   |
+LL |       let x: &'static bool = &unsafe { //~ borrowed value does not live long enough
+   |  _____________________________^
+LL | |         Foo { a: &1 }.b == Foo { a: &2 }.b
+LL | |     };
+   | |_____^ temporary value does not live long enough
+LL |   }
+   |   - temporary value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/const-fn-error.rs b/src/test/ui/const-fn-error.rs
index 17dc9f9..6eda417 100644
--- a/src/test/ui/const-fn-error.rs
+++ b/src/test/ui/const-fn-error.rs
@@ -19,7 +19,6 @@
     for i in 0..x {
         //~^ ERROR E0015
         //~| ERROR E0019
-        //~| ERROR E0080
         sum += i;
     }
     sum
@@ -27,5 +26,5 @@
 
 #[allow(unused_variables)]
 fn main() {
-    let a : [i32; f(X)];
+    let a : [i32; f(X)]; //~ ERROR E0080
 }
diff --git a/src/test/ui/const-fn-error.stderr b/src/test/ui/const-fn-error.stderr
index 29edc27..cdbf86f 100644
--- a/src/test/ui/const-fn-error.stderr
+++ b/src/test/ui/const-fn-error.stderr
@@ -26,20 +26,16 @@
 LL |     for i in 0..x {
    |              ^^^^
 
-error[E0080]: constant evaluation error
-  --> $DIR/const-fn-error.rs:19:14
+error[E0080]: could not evaluate constant expression
+  --> $DIR/const-fn-error.rs:29:13
    |
 LL |     for i in 0..x {
-   |              ^^^^ calling non-const fn `<I as std::iter::IntoIterator><std::ops::Range<usize>>::into_iter`
+   |              ---- calling non-const fn `<I as std::iter::IntoIterator><std::ops::Range<usize>>::into_iter`
 ...
-LL |     let a : [i32; f(X)];
-   |                   ---- inside call to `f`
-   |
-note: for constant expression here
-  --> $DIR/const-fn-error.rs:30:13
-   |
-LL |     let a : [i32; f(X)];
-   |             ^^^^^^^^^^^
+LL |     let a : [i32; f(X)]; //~ ERROR E0080
+   |             ^^^^^^----^
+   |                   |
+   |                   inside call to `f`
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/const-len-underflow-separate-spans.rs b/src/test/ui/const-len-underflow-separate-spans.rs
index 453e332..20b8865 100644
--- a/src/test/ui/const-len-underflow-separate-spans.rs
+++ b/src/test/ui/const-len-underflow-separate-spans.rs
@@ -21,4 +21,5 @@
 fn main() {
     let a: [i8; LEN] = unimplemented!();
 //~^ ERROR E0080
+//~| ERROR E0080
 }
diff --git a/src/test/ui/const-len-underflow-separate-spans.stderr b/src/test/ui/const-len-underflow-separate-spans.stderr
index 48ff7a8..630828e 100644
--- a/src/test/ui/const-len-underflow-separate-spans.stderr
+++ b/src/test/ui/const-len-underflow-separate-spans.stderr
@@ -12,12 +12,23 @@
 LL | const LEN: usize = ONE - TWO;
    |                    ^^^^^^^^^ attempt to subtract with overflow
 
-error[E0080]: constant evaluation error
-  --> $DIR/const-len-underflow-separate-spans.rs:22:17
+error[E0080]: referenced constant
+  --> $DIR/const-len-underflow-separate-spans.rs:22:12
+   |
+LL | const LEN: usize = ONE - TWO;
+   |                    --------- attempt to subtract with overflow
+...
+LL |     let a: [i8; LEN] = unimplemented!();
+   |            ^^^^^^^^^
+
+error[E0080]: could not evaluate constant expression
+  --> $DIR/const-len-underflow-separate-spans.rs:22:12
    |
 LL |     let a: [i8; LEN] = unimplemented!();
-   |                 ^^^ referenced constant has errors
+   |            ^^^^^---^
+   |                 |
+   |                 referenced constant has errors
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/deriving-with-repr-packed.rs b/src/test/ui/deriving-with-repr-packed.rs
index 0c52829..4337509 100644
--- a/src/test/ui/deriving-with-repr-packed.rs
+++ b/src/test/ui/deriving-with-repr-packed.rs
@@ -33,7 +33,7 @@
 struct Y(usize);
 
 #[derive(PartialEq)]
-//~^ ERROR #[derive] can't be used on a non-Copy #[repr(packed)]
+//~^ ERROR #[derive] can't be used
 //~| hard error
 #[repr(packed)]
 struct X(Y);
diff --git a/src/test/ui/deriving-with-repr-packed.stderr b/src/test/ui/deriving-with-repr-packed.stderr
index 64aefbc..a7599c1 100644
--- a/src/test/ui/deriving-with-repr-packed.stderr
+++ b/src/test/ui/deriving-with-repr-packed.stderr
@@ -21,7 +21,7 @@
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
 
-error: #[derive] can't be used on a non-Copy #[repr(packed)] struct (error E0133)
+error: #[derive] can't be used on a #[repr(packed)] struct that does not derive Copy (error E0133)
   --> $DIR/deriving-with-repr-packed.rs:26:10
    |
 LL | #[derive(PartialEq, Eq)]
@@ -30,7 +30,7 @@
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
 
-error: #[derive] can't be used on a non-Copy #[repr(packed)] struct (error E0133)
+error: #[derive] can't be used on a #[repr(packed)] struct that does not derive Copy (error E0133)
   --> $DIR/deriving-with-repr-packed.rs:35:10
    |
 LL | #[derive(PartialEq)]
diff --git a/src/test/ui/did_you_mean/issue-31424.stderr b/src/test/ui/did_you_mean/issue-31424.stderr
index a80593e..9d0ab21 100644
--- a/src/test/ui/did_you_mean/issue-31424.stderr
+++ b/src/test/ui/did_you_mean/issue-31424.stderr
@@ -10,10 +10,12 @@
 error[E0596]: cannot borrow immutable argument `self` as mutable
   --> $DIR/issue-31424.rs:23:15
    |
-LL |     fn bar(self: &mut Self) {
-   |            --------------- consider changing this to `mut self: &mut Self`
 LL |         (&mut self).bar(); //~ ERROR cannot borrow
    |               ^^^^ cannot borrow mutably
+help: consider removing the `&mut`, as it is an immutable binding to a mutable reference
+   |
+LL |         self.bar(); //~ ERROR cannot borrow
+   |         ^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/error-codes/E0080.stderr b/src/test/ui/error-codes/E0080.stderr
index 25ec5c4..a213c2b 100644
--- a/src/test/ui/error-codes/E0080.stderr
+++ b/src/test/ui/error-codes/E0080.stderr
@@ -6,7 +6,7 @@
    |
    = note: #[deny(exceeding_bitshifts)] on by default
 
-error[E0080]: constant evaluation error
+error[E0080]: could not evaluate enum discriminant
   --> $DIR/E0080.rs:12:9
    |
 LL |     X = (1 << 500), //~ ERROR E0080
@@ -20,13 +20,13 @@
    |
    = note: #[deny(const_err)] on by default
 
-error: constant evaluation error
+error: this expression will panic at runtime
   --> $DIR/E0080.rs:14:9
    |
 LL |     Y = (1 / 0) //~ ERROR E0080
    |         ^^^^^^^ attempt to divide by zero
 
-error[E0080]: constant evaluation error
+error[E0080]: could not evaluate enum discriminant
   --> $DIR/E0080.rs:14:9
    |
 LL |     Y = (1 / 0) //~ ERROR E0080
diff --git a/src/test/ui/error-codes/E0152.rs b/src/test/ui/error-codes/E0152.rs
index ae501b9..8fbad7b 100644
--- a/src/test/ui/error-codes/E0152.rs
+++ b/src/test/ui/error-codes/E0152.rs
@@ -10,7 +10,7 @@
 
 #![feature(lang_items)]
 
-#[lang = "panic_fmt"]
+#[lang = "panic_impl"]
 struct Foo; //~ ERROR E0152
 
 fn main() {
diff --git a/src/test/ui/error-codes/E0152.stderr b/src/test/ui/error-codes/E0152.stderr
index f67022b..c7f5f36 100644
--- a/src/test/ui/error-codes/E0152.stderr
+++ b/src/test/ui/error-codes/E0152.stderr
@@ -1,4 +1,4 @@
-error[E0152]: duplicate lang item found: `panic_fmt`.
+error[E0152]: duplicate lang item found: `panic_impl`.
   --> $DIR/E0152.rs:14:1
    |
 LL | struct Foo; //~ ERROR E0152
diff --git a/src/test/ui/error-codes/E0423.rs b/src/test/ui/error-codes/E0423.rs
index f5fea77..7d71499 100644
--- a/src/test/ui/error-codes/E0423.rs
+++ b/src/test/ui/error-codes/E0423.rs
@@ -13,3 +13,22 @@
 
     let f = Foo(); //~ ERROR E0423
 }
+
+fn bar() {
+    struct S { x: i32, y: i32 }
+    #[derive(PartialEq)]
+    struct T {}
+
+    if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); }
+    //~^ ERROR E0423
+    //~|  expected type, found `1`
+    if T {} == T {} { println!("Ok"); }
+    //~^ ERROR E0423
+    //~| ERROR expected expression, found `==`
+}
+
+fn foo() {
+    for _ in std::ops::Range { start: 0, end: 10 } {}
+    //~^ ERROR E0423
+    //~| ERROR expected type, found `0`
+}
diff --git a/src/test/ui/error-codes/E0423.stderr b/src/test/ui/error-codes/E0423.stderr
index ef24295..477c698 100644
--- a/src/test/ui/error-codes/E0423.stderr
+++ b/src/test/ui/error-codes/E0423.stderr
@@ -1,9 +1,48 @@
+error: expected type, found `1`
+  --> $DIR/E0423.rs:22:39
+   |
+LL |     if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); }
+   |                                       ^ expecting a type here because of type ascription
+
+error: expected expression, found `==`
+  --> $DIR/E0423.rs:25:13
+   |
+LL |     if T {} == T {} { println!("Ok"); }
+   |             ^^ expected expression
+
+error: expected type, found `0`
+  --> $DIR/E0423.rs:31:39
+   |
+LL |     for _ in std::ops::Range { start: 0, end: 10 } {}
+   |                                       ^ expecting a type here because of type ascription
+
 error[E0423]: expected function, found struct `Foo`
   --> $DIR/E0423.rs:14:13
    |
 LL |     let f = Foo(); //~ ERROR E0423
-   |             ^^^ did you mean `Foo { /* fields */ }`?
+   |             ^^^
+   |             |
+   |             did you mean `foo`?
+   |             did you mean `Foo { /* fields */ }`?
 
-error: aborting due to previous error
+error[E0423]: expected value, found struct `S`
+  --> $DIR/E0423.rs:22:32
+   |
+LL |     if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); }
+   |                                ^ did you mean `(S { /* fields */ })`?
+
+error[E0423]: expected value, found struct `T`
+  --> $DIR/E0423.rs:25:8
+   |
+LL |     if T {} == T {} { println!("Ok"); }
+   |        ^ did you mean `(T { /* fields */ })`?
+
+error[E0423]: expected value, found struct `std::ops::Range`
+  --> $DIR/E0423.rs:31:14
+   |
+LL |     for _ in std::ops::Range { start: 0, end: 10 } {}
+   |              ^^^^^^^^^^^^^^^ did you mean `(std::ops::Range { /* fields */ })`?
+
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0423`.
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/ui/feature-gate-doc_keyword.rs
similarity index 81%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/ui/feature-gate-doc_keyword.rs
index e7ffbe8..2ff4462 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/ui/feature-gate-doc_keyword.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
-
-fn main() {}
+#[doc(keyword = "match")] //~ ERROR: #[doc(keyword = "...")] is experimental
+/// wonderful
+mod foo{}
diff --git a/src/test/ui/feature-gate-doc_keyword.stderr b/src/test/ui/feature-gate-doc_keyword.stderr
new file mode 100644
index 0000000..e4f5109
--- /dev/null
+++ b/src/test/ui/feature-gate-doc_keyword.stderr
@@ -0,0 +1,11 @@
+error[E0658]: #[doc(keyword = "...")] is experimental (see issue #51315)
+  --> $DIR/feature-gate-doc_keyword.rs:11:1
+   |
+LL | #[doc(keyword = "match")] //~ ERROR: #[doc(keyword = "...")] is experimental
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(doc_keyword)] to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gate-global_allocator.stderr b/src/test/ui/feature-gate-global_allocator.stderr
deleted file mode 100644
index 9f8b98e..0000000
--- a/src/test/ui/feature-gate-global_allocator.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0658]: the `#[global_allocator]` attribute is an experimental feature (see issue #27389)
-  --> $DIR/feature-gate-global_allocator.rs:11:1
-   |
-LL | #[global_allocator] //~ ERROR: attribute is an experimental feature
-   | ^^^^^^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(global_allocator)] to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gate-repr_transparent.stderr b/src/test/ui/feature-gate-repr_transparent.stderr
deleted file mode 100644
index a4ffaa2..0000000
--- a/src/test/ui/feature-gate-repr_transparent.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0658]: the `#[repr(transparent)]` attribute is experimental (see issue #43036)
-  --> $DIR/feature-gate-repr_transparent.rs:11:1
-   |
-LL | #[repr(transparent)] //~ error: the `#[repr(transparent)]` attribute is experimental
-   | ^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(repr_transparent)] to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gate-trivial_bounds.rs b/src/test/ui/feature-gate-trivial_bounds.rs
index e72b878..dba66e0 100644
--- a/src/test/ui/feature-gate-trivial_bounds.rs
+++ b/src/test/ui/feature-gate-trivial_bounds.rs
@@ -28,7 +28,7 @@
 type Y where i32: Foo = (); // OK - bound is ignored
 
 impl Foo for () where i32: Foo { //~ ERROR
-    fn test(&self) { //~ ERROR
+    fn test(&self) {
         3i32.test();
         Foo::test(&4i32);
         generic_function(5i32);
@@ -60,7 +60,7 @@
 }
 
 struct TwoStrs(str, str) where str: Sized; //~ ERROR
-//~^ ERROR
+
 
 fn unsized_local() where Dst<A>: Sized { //~ ERROR
     let x: Dst<A> = *(Box::new(Dst { x: 1 }) as Box<Dst<A>>);
diff --git a/src/test/ui/feature-gate-trivial_bounds.stderr b/src/test/ui/feature-gate-trivial_bounds.stderr
index 32b2631..9c2c806 100644
--- a/src/test/ui/feature-gate-trivial_bounds.stderr
+++ b/src/test/ui/feature-gate-trivial_bounds.stderr
@@ -38,7 +38,7 @@
   --> $DIR/feature-gate-trivial_bounds.rs:30:1
    |
 LL | / impl Foo for () where i32: Foo { //~ ERROR
-LL | |     fn test(&self) { //~ ERROR
+LL | |     fn test(&self) {
 LL | |         3i32.test();
 LL | |         Foo::test(&4i32);
 LL | |         generic_function(5i32);
@@ -97,15 +97,6 @@
    = help: see issue #48214
    = help: add #![feature(trivial_bounds)] to the crate attributes to enable
 
-error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
-  --> $DIR/feature-gate-trivial_bounds.rs:62:16
-   |
-LL | struct TwoStrs(str, str) where str: Sized; //~ ERROR
-   |                ^^^ `str` does not have a constant size known at compile-time
-   |
-   = help: the trait `std::marker::Sized` is not implemented for `str`
-   = note: only the last field of a struct may have a dynamically sized type
-
 error[E0277]: the trait bound `A + 'static: std::marker::Sized` is not satisfied in `Dst<A + 'static>`
   --> $DIR/feature-gate-trivial_bounds.rs:65:1
    |
@@ -131,22 +122,6 @@
    = help: see issue #48214
    = help: add #![feature(trivial_bounds)] to the crate attributes to enable
 
-error[E0277]: the trait bound `i32: Foo` is not satisfied
-  --> $DIR/feature-gate-trivial_bounds.rs:31:5
-   |
-LL | /     fn test(&self) { //~ ERROR
-LL | |         3i32.test();
-LL | |         Foo::test(&4i32);
-LL | |         generic_function(5i32);
-LL | |     }
-   | |_____^ the trait `Foo` is not implemented for `i32`
-   |
-note: required by `Foo`
-  --> $DIR/feature-gate-trivial_bounds.rs:14:1
-   |
-LL | pub trait Foo {
-   | ^^^^^^^^^^^^^
-
-error: aborting due to 13 previous errors
+error: aborting due to 11 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs
index 76fb09f..db50b95 100644
--- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs
+++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs
@@ -59,7 +59,9 @@
 #![start                     = "x4300"] //~ WARN unused attribute
 // see issue-43106-gating-of-test.rs for crate-level; but non crate-level is below at "4200"
 // see issue-43106-gating-of-bench.rs for crate-level; but non crate-level is below at "4100"
-#![repr                       = "3900"] //~ WARN unused attribute
+#![repr                       = "3900"]
+//~^ WARN unused attribute
+//~| WARN `repr` attribute isn't configurable with a literal
 #![path                       = "3800"] //~ WARN unused attribute
 #![abi                        = "3700"] //~ WARN unused attribute
 #![automatically_derived      = "3600"] //~ WARN unused attribute
@@ -309,20 +311,25 @@
 
 #[repr = "3900"]
 //~^ WARN unused attribute
+//~| WARN `repr` attribute isn't configurable with a literal
 mod repr {
     mod inner { #![repr="3900"] }
     //~^ WARN unused attribute
+    //~| WARN `repr` attribute isn't configurable with a literal
 
     #[repr = "3900"] fn f() { }
     //~^ WARN unused attribute
+    //~| WARN `repr` attribute isn't configurable with a literal
 
     struct S;
 
     #[repr = "3900"] type T = S;
     //~^ WARN unused attribute
+    //~| WARN `repr` attribute isn't configurable with a literal
 
     #[repr = "3900"] impl S { }
     //~^ WARN unused attribute
+    //~| WARN `repr` attribute isn't configurable with a literal
 }
 
 #[path = "3800"]
diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr
index f8e5f58..f351a9e 100644
--- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr
+++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr
@@ -1,11 +1,11 @@
 warning: macro_escape is a deprecated synonym for macro_use
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:493:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:500:1
    |
 LL | #[macro_escape]
    | ^^^^^^^^^^^^^^^
 
 warning: macro_escape is a deprecated synonym for macro_use
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:496:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:503:17
    |
 LL |     mod inner { #![macro_escape] }
    |                 ^^^^^^^^^^^^^^^^
@@ -43,151 +43,206 @@
    |                                 ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:112:8
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:114:8
    |
 LL | #[warn(x5400)]
    |        ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:115:25
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:117:25
    |
 LL |     mod inner { #![warn(x5400)] }
    |                         ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:118:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:120:12
    |
 LL |     #[warn(x5400)] fn f() { }
    |            ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:121:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:123:12
    |
 LL |     #[warn(x5400)] struct S;
    |            ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:124:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:126:12
    |
 LL |     #[warn(x5400)] type T = S;
    |            ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:127:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:129:12
    |
 LL |     #[warn(x5400)] impl S { }
    |            ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:131:9
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:133:9
    |
 LL | #[allow(x5300)]
    |         ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:134:26
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:136:26
    |
 LL |     mod inner { #![allow(x5300)] }
    |                          ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:137:13
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:139:13
    |
 LL |     #[allow(x5300)] fn f() { }
    |             ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:140:13
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:142:13
    |
 LL |     #[allow(x5300)] struct S;
    |             ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:143:13
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:145:13
    |
 LL |     #[allow(x5300)] type T = S;
    |             ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:146:13
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:148:13
    |
 LL |     #[allow(x5300)] impl S { }
    |             ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:150:10
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:152:10
    |
 LL | #[forbid(x5200)]
    |          ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:153:27
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:155:27
    |
 LL |     mod inner { #![forbid(x5200)] }
    |                           ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:156:14
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:158:14
    |
 LL |     #[forbid(x5200)] fn f() { }
    |              ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:159:14
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:161:14
    |
 LL |     #[forbid(x5200)] struct S;
    |              ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:162:14
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:164:14
    |
 LL |     #[forbid(x5200)] type T = S;
    |              ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:165:14
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:167:14
    |
 LL |     #[forbid(x5200)] impl S { }
    |              ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:169:8
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:171:8
    |
 LL | #[deny(x5100)]
    |        ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:172:25
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:174:25
    |
 LL |     mod inner { #![deny(x5100)] }
    |                         ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:175:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:177:12
    |
 LL |     #[deny(x5100)] fn f() { }
    |            ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:178:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:180:12
    |
 LL |     #[deny(x5100)] struct S;
    |            ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:181:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:183:12
    |
 LL |     #[deny(x5100)] type T = S;
    |            ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:184:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:186:12
    |
 LL |     #[deny(x5100)] impl S { }
    |            ^^^^^
 
+warning: `repr` attribute isn't configurable with a literal
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:316:17
+   |
+LL |     mod inner { #![repr="3900"] }
+   |                 ^^^^^^^^^^^^^^^ needs a hint
+   |
+   = note: #[warn(bad_repr)] on by default
+   = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]`
+   = note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html>
+
+warning: `repr` attribute isn't configurable with a literal
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:320:5
+   |
+LL |     #[repr = "3900"] fn f() { }
+   |     ^^^^^^^^^^^^^^^^ needs a hint
+   |
+   = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]`
+   = note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html>
+
+warning: `repr` attribute isn't configurable with a literal
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:326:5
+   |
+LL |     #[repr = "3900"] type T = S;
+   |     ^^^^^^^^^^^^^^^^ needs a hint
+   |
+   = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]`
+   = note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html>
+
+warning: `repr` attribute isn't configurable with a literal
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:330:5
+   |
+LL |     #[repr = "3900"] impl S { }
+   |     ^^^^^^^^^^^^^^^^ needs a hint
+   |
+   = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]`
+   = note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html>
+
+warning: `repr` attribute isn't configurable with a literal
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:312:1
+   |
+LL | #[repr = "3900"]
+   | ^^^^^^^^^^^^^^^^ needs a hint
+   |
+   = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]`
+   = note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html>
+
+warning: `repr` attribute isn't configurable with a literal
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:62:1
+   |
+LL | #![repr                       = "3900"]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ needs a hint
+   |
+   = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]`
+   = note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html>
+
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:192:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:194:5
    |
 LL |     #[macro_use] fn f() { }
    |     ^^^^^^^^^^^^
@@ -199,277 +254,277 @@
    |         ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:195:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:197:5
    |
 LL |     #[macro_use] struct S;
    |     ^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:198:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:200:5
    |
 LL |     #[macro_use] type T = S;
    |     ^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:201:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:203:5
    |
 LL |     #[macro_use] impl S { }
    |     ^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:208:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:210:17
    |
 LL |     mod inner { #![macro_export="4800"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:211:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:213:5
    |
 LL |     #[macro_export = "4800"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:214:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:216:5
    |
 LL |     #[macro_export = "4800"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:217:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:219:5
    |
 LL |     #[macro_export = "4800"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:220:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:222:5
    |
 LL |     #[macro_export = "4800"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:205:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:207:1
    |
 LL | #[macro_export = "4800"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:227:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:229:17
    |
 LL |     mod inner { #![plugin_registrar="4700"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:232:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:234:5
    |
 LL |     #[plugin_registrar = "4700"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:235:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:237:5
    |
 LL |     #[plugin_registrar = "4700"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:238:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:240:5
    |
 LL |     #[plugin_registrar = "4700"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:224:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:226:1
    |
 LL | #[plugin_registrar = "4700"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:245:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:247:17
    |
 LL |     mod inner { #![main="4300"] }
    |                 ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:250:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:252:5
    |
 LL |     #[main = "4400"] struct S;
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:253:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:255:5
    |
 LL |     #[main = "4400"] type T = S;
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:256:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:258:5
    |
 LL |     #[main = "4400"] impl S { }
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:242:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:244:1
    |
 LL | #[main = "4400"]
    | ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:263:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:265:17
    |
 LL |     mod inner { #![start="4300"] }
    |                 ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:268:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:270:5
    |
 LL |     #[start = "4300"] struct S;
    |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:271:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:273:5
    |
 LL |     #[start = "4300"] type T = S;
    |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:274:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:276:5
    |
 LL |     #[start = "4300"] impl S { }
    |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:260:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:262:1
    |
 LL | #[start = "4300"]
    | ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:313:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:316:17
    |
 LL |     mod inner { #![repr="3900"] }
    |                 ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:316:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:320:5
    |
 LL |     #[repr = "3900"] fn f() { }
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:321:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:326:5
    |
 LL |     #[repr = "3900"] type T = S;
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:324:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:330:5
    |
 LL |     #[repr = "3900"] impl S { }
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:310:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:312:1
    |
 LL | #[repr = "3900"]
    | ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:332:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:339:5
    |
 LL |     #[path = "3800"] fn f() { }
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:335:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:342:5
    |
 LL |     #[path = "3800"]  struct S;
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:338:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:345:5
    |
 LL |     #[path = "3800"] type T = S;
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:341:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:348:5
    |
 LL |     #[path = "3800"] impl S { }
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:348:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:355:17
    |
 LL |     mod inner { #![abi="3700"] }
    |                 ^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:351:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:358:5
    |
 LL |     #[abi = "3700"] fn f() { }
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:354:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:361:5
    |
 LL |     #[abi = "3700"] struct S;
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:357:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:364:5
    |
 LL |     #[abi = "3700"] type T = S;
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:360:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:367:5
    |
 LL |     #[abi = "3700"] impl S { }
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:345:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:352:1
    |
 LL | #[abi = "3700"]
    | ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:367:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:374:17
    |
 LL |     mod inner { #![automatically_derived="3600"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:370:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:377:5
    |
 LL |     #[automatically_derived = "3600"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:373:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:380:5
    |
 LL |     #[automatically_derived = "3600"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:376:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:383:5
    |
 LL |     #[automatically_derived = "3600"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:379:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:386:5
    |
 LL |     #[automatically_derived = "3600"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:364:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:371:1
    |
 LL | #[automatically_derived = "3600"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: function is marked #[no_mangle], but not exported
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:387:27
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:394:27
    |
 LL |     #[no_mangle = "3500"] fn f() { }
    |                           -^^^^^^^^^
@@ -479,709 +534,709 @@
    = note: #[warn(private_no_mangle_fns)] on by default
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:400:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:407:17
    |
 LL |     mod inner { #![no_link="3400"] }
    |                 ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:403:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:410:5
    |
 LL |     #[no_link = "3400"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:406:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:413:5
    |
 LL |     #[no_link = "3400"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:409:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:416:5
    |
 LL |     #[no_link = "3400"]type T = S;
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:412:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:419:5
    |
 LL |     #[no_link = "3400"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:397:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:404:1
    |
 LL | #[no_link = "3400"]
    | ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:419:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:426:17
    |
 LL |     mod inner { #![should_panic="3200"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:422:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:429:5
    |
 LL |     #[should_panic = "3200"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:425:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:432:5
    |
 LL |     #[should_panic = "3200"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:428:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:435:5
    |
 LL |     #[should_panic = "3200"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:431:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:438:5
    |
 LL |     #[should_panic = "3200"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:416:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:423:1
    |
 LL | #[should_panic = "3200"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:438:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:445:17
    |
 LL |     mod inner { #![ignore="3100"] }
    |                 ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:441:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:448:5
    |
 LL |     #[ignore = "3100"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:444:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:451:5
    |
 LL |     #[ignore = "3100"] struct S;
    |     ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:447:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:454:5
    |
 LL |     #[ignore = "3100"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:450:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:457:5
    |
 LL |     #[ignore = "3100"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:435:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:442:1
    |
 LL | #[ignore = "3100"]
    | ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:457:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:464:17
    |
 LL |     mod inner { #![no_implicit_prelude="3000"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:460:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:467:5
    |
 LL |     #[no_implicit_prelude = "3000"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:463:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:470:5
    |
 LL |     #[no_implicit_prelude = "3000"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:466:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:473:5
    |
 LL |     #[no_implicit_prelude = "3000"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:469:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:476:5
    |
 LL |     #[no_implicit_prelude = "3000"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:454:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:461:1
    |
 LL | #[no_implicit_prelude = "3000"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:476:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:483:17
    |
 LL |     mod inner { #![reexport_test_harness_main="2900"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:479:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:486:5
    |
 LL |     #[reexport_test_harness_main = "2900"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:482:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:489:5
    |
 LL |     #[reexport_test_harness_main = "2900"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:485:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:492:5
    |
 LL |     #[reexport_test_harness_main = "2900"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:488:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:495:5
    |
 LL |     #[reexport_test_harness_main = "2900"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:473:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:480:1
    |
 LL | #[reexport_test_harness_main = "2900"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:499:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:506:5
    |
 LL |     #[macro_escape] fn f() { }
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:502:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:509:5
    |
 LL |     #[macro_escape] struct S;
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:505:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:512:5
    |
 LL |     #[macro_escape] type T = S;
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:508:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:515:5
    |
 LL |     #[macro_escape] impl S { }
    |     ^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:516:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:523:17
    |
 LL |     mod inner { #![no_std="2600"] }
    |                 ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:516:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:523:17
    |
 LL |     mod inner { #![no_std="2600"] }
    |                 ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:520:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:527:5
    |
 LL |     #[no_std = "2600"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:520:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:527:5
    |
 LL |     #[no_std = "2600"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:524:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:531:5
    |
 LL |     #[no_std = "2600"] struct S;
    |     ^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:524:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:531:5
    |
 LL |     #[no_std = "2600"] struct S;
    |     ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:528:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:535:5
    |
 LL |     #[no_std = "2600"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:528:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:535:5
    |
 LL |     #[no_std = "2600"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:532:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:539:5
    |
 LL |     #[no_std = "2600"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:532:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:539:5
    |
 LL |     #[no_std = "2600"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:512:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:519:1
    |
 LL | #[no_std = "2600"]
    | ^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:512:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:519:1
    |
 LL | #[no_std = "2600"]
    | ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:671:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:678:17
    |
 LL |     mod inner { #![crate_name="0900"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:671:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:678:17
    |
 LL |     mod inner { #![crate_name="0900"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:675:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:682:5
    |
 LL |     #[crate_name = "0900"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:675:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:682:5
    |
 LL |     #[crate_name = "0900"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:679:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:686:5
    |
 LL |     #[crate_name = "0900"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:679:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:686:5
    |
 LL |     #[crate_name = "0900"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:683:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:690:5
    |
 LL |     #[crate_name = "0900"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:683:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:690:5
    |
 LL |     #[crate_name = "0900"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:687:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:694:5
    |
 LL |     #[crate_name = "0900"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:687:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:694:5
    |
 LL |     #[crate_name = "0900"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:667:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:674:1
    |
 LL | #[crate_name = "0900"]
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:667:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:674:1
    |
 LL | #[crate_name = "0900"]
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:703:17
    |
 LL |     mod inner { #![crate_type="0800"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:703:17
    |
 LL |     mod inner { #![crate_type="0800"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:700:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:707:5
    |
 LL |     #[crate_type = "0800"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:700:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:707:5
    |
 LL |     #[crate_type = "0800"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:704:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:711:5
    |
 LL |     #[crate_type = "0800"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:704:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:711:5
    |
 LL |     #[crate_type = "0800"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:708:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:715:5
    |
 LL |     #[crate_type = "0800"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:708:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:715:5
    |
 LL |     #[crate_type = "0800"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:712:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:719:5
    |
 LL |     #[crate_type = "0800"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:712:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:719:5
    |
 LL |     #[crate_type = "0800"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:699:1
    |
 LL | #[crate_type = "0800"]
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:692:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:699:1
    |
 LL | #[crate_type = "0800"]
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:728:17
    |
 LL |     mod inner { #![feature(x0600)] }
    |                 ^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:728:17
    |
 LL |     mod inner { #![feature(x0600)] }
    |                 ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:725:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:732:5
    |
 LL |     #[feature(x0600)] fn f() { }
    |     ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:725:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:732:5
    |
 LL |     #[feature(x0600)] fn f() { }
    |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:736:5
    |
 LL |     #[feature(x0600)] struct S;
    |     ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:736:5
    |
 LL |     #[feature(x0600)] struct S;
    |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:733:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:740:5
    |
 LL |     #[feature(x0600)] type T = S;
    |     ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:733:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:740:5
    |
 LL |     #[feature(x0600)] type T = S;
    |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:737:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:744:5
    |
 LL |     #[feature(x0600)] impl S { }
    |     ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:737:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:744:5
    |
 LL |     #[feature(x0600)] impl S { }
    |     ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:724:1
    |
 LL | #[feature(x0600)]
    | ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:724:1
    |
 LL | #[feature(x0600)]
    | ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:747:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:754:17
    |
 LL |     mod inner { #![no_main="0400"] }
    |                 ^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:747:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:754:17
    |
 LL |     mod inner { #![no_main="0400"] }
    |                 ^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:751:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:758:5
    |
 LL |     #[no_main = "0400"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:751:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:758:5
    |
 LL |     #[no_main = "0400"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:755:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:762:5
    |
 LL |     #[no_main = "0400"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:755:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:762:5
    |
 LL |     #[no_main = "0400"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:759:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:766:5
    |
 LL |     #[no_main = "0400"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:759:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:766:5
    |
 LL |     #[no_main = "0400"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:763:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:770:5
    |
 LL |     #[no_main = "0400"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:763:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:770:5
    |
 LL |     #[no_main = "0400"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:743:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:750:1
    |
 LL | #[no_main = "0400"]
    | ^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:743:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:750:1
    |
 LL | #[no_main = "0400"]
    | ^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:785:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:792:17
    |
 LL |     mod inner { #![recursion_limit="0200"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:785:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:792:17
    |
 LL |     mod inner { #![recursion_limit="0200"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:789:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:796:5
    |
 LL |     #[recursion_limit="0200"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:789:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:796:5
    |
 LL |     #[recursion_limit="0200"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:800:5
    |
 LL |     #[recursion_limit="0200"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:800:5
    |
 LL |     #[recursion_limit="0200"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:797:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:804:5
    |
 LL |     #[recursion_limit="0200"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:797:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:804:5
    |
 LL |     #[recursion_limit="0200"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:808:5
    |
 LL |     #[recursion_limit="0200"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:808:5
    |
 LL |     #[recursion_limit="0200"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:781:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:788:1
    |
 LL | #[recursion_limit="0200"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:781:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:788:1
    |
 LL | #[recursion_limit="0200"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:810:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:817:17
    |
 LL |     mod inner { #![type_length_limit="0100"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:810:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:817:17
    |
 LL |     mod inner { #![type_length_limit="0100"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:814:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:821:5
    |
 LL |     #[type_length_limit="0100"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:814:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:821:5
    |
 LL |     #[type_length_limit="0100"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:818:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:825:5
    |
 LL |     #[type_length_limit="0100"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:818:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:825:5
    |
 LL |     #[type_length_limit="0100"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:822:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:829:5
    |
 LL |     #[type_length_limit="0100"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:822:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:829:5
    |
 LL |     #[type_length_limit="0100"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:826:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:833:5
    |
 LL |     #[type_length_limit="0100"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:826:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:833:5
    |
 LL |     #[type_length_limit="0100"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:806:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:813:1
    |
 LL | #[type_length_limit="0100"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: #![foo]
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:806:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:813:1
    |
 LL | #[type_length_limit="0100"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1213,53 +1268,53 @@
 warning: unused attribute
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:62:1
    |
-LL | #![repr                       = "3900"] //~ WARN unused attribute
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:63:1
-   |
-LL | #![path                       = "3800"] //~ WARN unused attribute
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:64:1
-   |
-LL | #![abi                        = "3700"] //~ WARN unused attribute
+LL | #![repr                       = "3900"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:65:1
    |
-LL | #![automatically_derived      = "3600"] //~ WARN unused attribute
+LL | #![path                       = "3800"] //~ WARN unused attribute
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: unused attribute
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:66:1
+   |
+LL | #![abi                        = "3700"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:67:1
    |
-LL | #![no_link                    = "3400"] //~ WARN unused attribute
+LL | #![automatically_derived      = "3600"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:69:1
    |
+LL | #![no_link                    = "3400"] //~ WARN unused attribute
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: unused attribute
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:71:1
+   |
 LL | #![should_panic               = "3200"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:70:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:72:1
    |
 LL | #![ignore                     = "3100"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:76:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:78:1
    |
 LL | #![proc_macro_derive          = "2500"] //~ WARN unused attribute
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: compilation successful
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:837:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:844:1
    |
 LL | / fn main() { //~ ERROR compilation successful
 LL | |     println!("Hello World");
diff --git a/src/test/ui/generator/pattern-borrow.nll.stderr b/src/test/ui/generator/pattern-borrow.nll.stderr
deleted file mode 100644
index 48f2348..0000000
--- a/src/test/ui/generator/pattern-borrow.nll.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0626]: borrow may still be in use when generator yields
-  --> $DIR/pattern-borrow.rs:19:24
-   |
-LL |         if let Test::A(ref _a) = test { //~ ERROR borrow may still be in use when generator yields
-   |                        ^^^^^^
-LL |             yield ();
-   |             -------- possible yield occurs here
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0626`.
diff --git a/src/test/ui/hygiene/no_implicit_prelude.stderr b/src/test/ui/hygiene/no_implicit_prelude.stderr
index 5753d1a..b3d82e9 100644
--- a/src/test/ui/hygiene/no_implicit_prelude.stderr
+++ b/src/test/ui/hygiene/no_implicit_prelude.stderr
@@ -22,7 +22,7 @@
    |
    = help: items from traits can only be used if the trait is in scope
    = note: the following trait is implemented but not in scope, perhaps add a `use` for it:
-           candidate #1: `use std::clone::Clone;`
+           `use std::clone::Clone;`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/hygiene/trait_items.stderr b/src/test/ui/hygiene/trait_items.stderr
index 56d9c58..1b2975b 100644
--- a/src/test/ui/hygiene/trait_items.stderr
+++ b/src/test/ui/hygiene/trait_items.stderr
@@ -9,7 +9,7 @@
    |
    = help: items from traits can only be used if the trait is in scope
    = note: the following trait is implemented but not in scope, perhaps add a `use` for it:
-           candidate #1: `use foo::T;`
+           `use foo::T;`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/impl-trait/auto-trait-leak.rs b/src/test/ui/impl-trait/auto-trait-leak.rs
index 54d5487..abb3682 100644
--- a/src/test/ui/impl-trait/auto-trait-leak.rs
+++ b/src/test/ui/impl-trait/auto-trait-leak.rs
@@ -13,27 +13,9 @@
 use std::cell::Cell;
 use std::rc::Rc;
 
-// Fast path, main can see the concrete type returned.
-fn before() -> impl Fn(i32) {
-    let p = Rc::new(Cell::new(0));
-    move |x| p.set(x)
-}
-
 fn send<T: Send>(_: T) {}
 
 fn main() {
-    send(before());
-    //~^ ERROR the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied
-
-    send(after());
-    //~^ ERROR the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied
-}
-
-// Deferred path, main has to wait until typeck finishes,
-// to check if the return type of after is Send.
-fn after() -> impl Fn(i32) {
-    let p = Rc::new(Cell::new(0));
-    move |x| p.set(x)
 }
 
 // Cycles should work as the deferred obligations are
@@ -41,7 +23,9 @@
 // return type, which can't depend on the obligation.
 fn cycle1() -> impl Clone {
     //~^ ERROR cycle detected
+    //~| ERROR cycle detected
     send(cycle2().clone());
+    //~^ ERROR Send` is not satisfied
 
     Rc::new(Cell::new(5))
 }
diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr
index efa9a58..4537c96 100644
--- a/src/test/ui/impl-trait/auto-trait-leak.stderr
+++ b/src/test/ui/impl-trait/auto-trait-leak.stderr
@@ -1,58 +1,65 @@
-error[E0277]: the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied in `impl std::ops::Fn<(i32,)>`
-  --> $DIR/auto-trait-leak.rs:25:5
+error[E0391]: cycle detected when processing `cycle1::{{exist-impl-Trait}}`
+  --> $DIR/auto-trait-leak.rs:24:16
    |
-LL |     send(before());
-   |     ^^^^ `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
+LL | fn cycle1() -> impl Clone {
+   |                ^^^^^^^^^^
    |
-   = help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::cell::Cell<i32>>`
-   = note: required because it appears within the type `[closure@$DIR/auto-trait-leak.rs:19:5: 19:22 p:std::rc::Rc<std::cell::Cell<i32>>]`
-   = note: required because it appears within the type `impl std::ops::Fn<(i32,)>`
-note: required by `send`
-  --> $DIR/auto-trait-leak.rs:22:1
-   |
-LL | fn send<T: Send>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0277]: the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied in `impl std::ops::Fn<(i32,)>`
-  --> $DIR/auto-trait-leak.rs:28:5
-   |
-LL |     send(after());
-   |     ^^^^ `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
-   |
-   = help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::cell::Cell<i32>>`
-   = note: required because it appears within the type `[closure@$DIR/auto-trait-leak.rs:36:5: 36:22 p:std::rc::Rc<std::cell::Cell<i32>>]`
-   = note: required because it appears within the type `impl std::ops::Fn<(i32,)>`
-note: required by `send`
-  --> $DIR/auto-trait-leak.rs:22:1
-   |
-LL | fn send<T: Send>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0391]: cycle detected when processing `cycle1`
-  --> $DIR/auto-trait-leak.rs:42:1
+note: ...which requires processing `cycle1`...
+  --> $DIR/auto-trait-leak.rs:24:1
    |
 LL | fn cycle1() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
 note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`...
-note: ...which requires processing `cycle2::{{impl-Trait}}`...
-  --> $DIR/auto-trait-leak.rs:49:16
+note: ...which requires processing `cycle2::{{exist-impl-Trait}}`...
+  --> $DIR/auto-trait-leak.rs:33:16
    |
 LL | fn cycle2() -> impl Clone {
    |                ^^^^^^^^^^
 note: ...which requires processing `cycle2`...
-  --> $DIR/auto-trait-leak.rs:49:1
+  --> $DIR/auto-trait-leak.rs:33:1
    |
 LL | fn cycle2() -> impl Clone {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`...
-note: ...which requires processing `cycle1::{{impl-Trait}}`...
-  --> $DIR/auto-trait-leak.rs:42:16
+   = note: ...which again requires processing `cycle1::{{exist-impl-Trait}}`, completing the cycle
+
+error[E0391]: cycle detected when processing `cycle1::{{exist-impl-Trait}}`
+  --> $DIR/auto-trait-leak.rs:24:16
    |
 LL | fn cycle1() -> impl Clone {
    |                ^^^^^^^^^^
-   = note: ...which again requires processing `cycle1`, completing the cycle
-note: cycle used when type-checking all item bodies
+   |
+note: ...which requires processing `cycle1`...
+  --> $DIR/auto-trait-leak.rs:24:1
+   |
+LL | fn cycle1() -> impl Clone {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`...
+note: ...which requires processing `cycle2::{{exist-impl-Trait}}`...
+  --> $DIR/auto-trait-leak.rs:33:16
+   |
+LL | fn cycle2() -> impl Clone {
+   |                ^^^^^^^^^^
+note: ...which requires processing `cycle2`...
+  --> $DIR/auto-trait-leak.rs:33:1
+   |
+LL | fn cycle2() -> impl Clone {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: ...which again requires processing `cycle1::{{exist-impl-Trait}}`, completing the cycle
+
+error[E0277]: the trait bound `std::rc::Rc<std::string::String>: std::marker::Send` is not satisfied in `impl std::clone::Clone`
+  --> $DIR/auto-trait-leak.rs:27:5
+   |
+LL |     send(cycle2().clone());
+   |     ^^^^ `std::rc::Rc<std::string::String>` cannot be sent between threads safely
+   |
+   = help: within `impl std::clone::Clone`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::string::String>`
+   = note: required because it appears within the type `impl std::clone::Clone`
+note: required by `send`
+  --> $DIR/auto-trait-leak.rs:16:1
+   |
+LL | fn send<T: Send>(_: T) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/impl-trait/auto-trait-leak2.rs b/src/test/ui/impl-trait/auto-trait-leak2.rs
new file mode 100644
index 0000000..16310e6
--- /dev/null
+++ b/src/test/ui/impl-trait/auto-trait-leak2.rs
@@ -0,0 +1,38 @@
+// Copyright 2016 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-tidy-linelength
+
+use std::cell::Cell;
+use std::rc::Rc;
+
+// Fast path, main can see the concrete type returned.
+fn before() -> impl Fn(i32) {
+    let p = Rc::new(Cell::new(0));
+    move |x| p.set(x)
+}
+
+fn send<T: Send>(_: T) {}
+
+fn main() {
+    send(before());
+    //~^ ERROR the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied
+
+    send(after());
+    //~^ ERROR the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied
+}
+
+// Deferred path, main has to wait until typeck finishes,
+// to check if the return type of after is Send.
+fn after() -> impl Fn(i32) {
+    let p = Rc::new(Cell::new(0));
+    move |x| p.set(x)
+}
+
diff --git a/src/test/ui/impl-trait/auto-trait-leak2.stderr b/src/test/ui/impl-trait/auto-trait-leak2.stderr
new file mode 100644
index 0000000..59623ae
--- /dev/null
+++ b/src/test/ui/impl-trait/auto-trait-leak2.stderr
@@ -0,0 +1,33 @@
+error[E0277]: the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied in `impl std::ops::Fn<(i32,)>`
+  --> $DIR/auto-trait-leak2.rs:25:5
+   |
+LL |     send(before());
+   |     ^^^^ `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
+   |
+   = help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::cell::Cell<i32>>`
+   = note: required because it appears within the type `[closure@$DIR/auto-trait-leak2.rs:19:5: 19:22 p:std::rc::Rc<std::cell::Cell<i32>>]`
+   = note: required because it appears within the type `impl std::ops::Fn<(i32,)>`
+note: required by `send`
+  --> $DIR/auto-trait-leak2.rs:22:1
+   |
+LL | fn send<T: Send>(_: T) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied in `impl std::ops::Fn<(i32,)>`
+  --> $DIR/auto-trait-leak2.rs:28:5
+   |
+LL |     send(after());
+   |     ^^^^ `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
+   |
+   = help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::cell::Cell<i32>>`
+   = note: required because it appears within the type `[closure@$DIR/auto-trait-leak2.rs:36:5: 36:22 p:std::rc::Rc<std::cell::Cell<i32>>]`
+   = note: required because it appears within the type `impl std::ops::Fn<(i32,)>`
+note: required by `send`
+  --> $DIR/auto-trait-leak2.rs:22:1
+   |
+LL | fn send<T: Send>(_: T) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/impl-trait/equality.rs b/src/test/ui/impl-trait/equality.rs
index b65e477..71fccc0 100644
--- a/src/test/ui/impl-trait/equality.rs
+++ b/src/test/ui/impl-trait/equality.rs
@@ -50,23 +50,4 @@
 }
 
 fn main() {
-    let _: u32 = hide(0_u32);
-    //~^ ERROR mismatched types
-    //~| expected type `u32`
-    //~| found type `impl Foo`
-    //~| expected u32, found anonymized type
-
-    let _: i32 = Leak::leak(hide(0_i32));
-    //~^ ERROR mismatched types
-    //~| expected type `i32`
-    //~| found type `<impl Foo as Leak>::T`
-    //~| expected i32, found associated type
-
-    let mut x = (hide(0_u32), hide(0_i32));
-    x = (x.1,
-    //~^ ERROR mismatched types
-    //~| expected u32, found i32
-         x.0);
-    //~^ ERROR mismatched types
-    //~| expected i32, found u32
 }
diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr
index 0f310df..e277d4e 100644
--- a/src/test/ui/impl-trait/equality.stderr
+++ b/src/test/ui/impl-trait/equality.stderr
@@ -15,43 +15,7 @@
    |
    = help: the trait `std::ops::Add<impl Foo>` is not implemented for `u32`
 
-error[E0308]: mismatched types
-  --> $DIR/equality.rs:53:18
-   |
-LL |     let _: u32 = hide(0_u32);
-   |                  ^^^^^^^^^^^ expected u32, found anonymized type
-   |
-   = note: expected type `u32`
-              found type `impl Foo`
-
-error[E0308]: mismatched types
-  --> $DIR/equality.rs:59:18
-   |
-LL |     let _: i32 = Leak::leak(hide(0_i32));
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^ expected i32, found associated type
-   |
-   = note: expected type `i32`
-              found type `<impl Foo as Leak>::T`
-
-error[E0308]: mismatched types
-  --> $DIR/equality.rs:66:10
-   |
-LL |     x = (x.1,
-   |          ^^^ expected u32, found i32
-   |
-   = note: expected type `impl Foo` (u32)
-              found type `impl Foo` (i32)
-
-error[E0308]: mismatched types
-  --> $DIR/equality.rs:69:10
-   |
-LL |          x.0);
-   |          ^^^ expected i32, found u32
-   |
-   = note: expected type `impl Foo` (i32)
-              found type `impl Foo` (u32)
-
-error: aborting due to 6 previous errors
+error: aborting due to 2 previous errors
 
 Some errors occurred: E0277, E0308.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/impl-trait/equality2.rs b/src/test/ui/impl-trait/equality2.rs
new file mode 100644
index 0000000..ec3dc15
--- /dev/null
+++ b/src/test/ui/impl-trait/equality2.rs
@@ -0,0 +1,54 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(specialization)]
+
+trait Foo: Copy + ToString {}
+
+impl<T: Copy + ToString> Foo for T {}
+
+fn hide<T: Foo>(x: T) -> impl Foo {
+    x
+}
+
+trait Leak: Sized {
+    type T;
+    fn leak(self) -> Self::T;
+}
+impl<T> Leak for T {
+    default type T = ();
+    default fn leak(self) -> Self::T { panic!() }
+}
+impl Leak for i32 {
+    type T = i32;
+    fn leak(self) -> i32 { self }
+}
+
+fn main() {
+    let _: u32 = hide(0_u32);
+    //~^ ERROR mismatched types
+    //~| expected type `u32`
+    //~| found type `impl Foo`
+    //~| expected u32, found anonymized type
+
+    let _: i32 = Leak::leak(hide(0_i32));
+    //~^ ERROR mismatched types
+    //~| expected type `i32`
+    //~| found type `<impl Foo as Leak>::T`
+    //~| expected i32, found associated type
+
+    let mut x = (hide(0_u32), hide(0_i32));
+    x = (x.1,
+    //~^ ERROR mismatched types
+    //~| expected u32, found i32
+         x.0);
+    //~^ ERROR mismatched types
+    //~| expected i32, found u32
+}
diff --git a/src/test/ui/impl-trait/equality2.stderr b/src/test/ui/impl-trait/equality2.stderr
new file mode 100644
index 0000000..e4ff2f6
--- /dev/null
+++ b/src/test/ui/impl-trait/equality2.stderr
@@ -0,0 +1,39 @@
+error[E0308]: mismatched types
+  --> $DIR/equality2.rs:35:18
+   |
+LL |     let _: u32 = hide(0_u32);
+   |                  ^^^^^^^^^^^ expected u32, found anonymized type
+   |
+   = note: expected type `u32`
+              found type `impl Foo`
+
+error[E0308]: mismatched types
+  --> $DIR/equality2.rs:41:18
+   |
+LL |     let _: i32 = Leak::leak(hide(0_i32));
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^ expected i32, found associated type
+   |
+   = note: expected type `i32`
+              found type `<impl Foo as Leak>::T`
+
+error[E0308]: mismatched types
+  --> $DIR/equality2.rs:48:10
+   |
+LL |     x = (x.1,
+   |          ^^^ expected u32, found i32
+   |
+   = note: expected type `impl Foo` (u32)
+              found type `impl Foo` (i32)
+
+error[E0308]: mismatched types
+  --> $DIR/equality2.rs:51:10
+   |
+LL |          x.0);
+   |          ^^^ expected i32, found u32
+   |
+   = note: expected type `impl Foo` (i32)
+              found type `impl Foo` (u32)
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/impl-trait/region-escape-via-bound.rs b/src/test/ui/impl-trait/region-escape-via-bound.rs
index e73f156..c40c5f4 100644
--- a/src/test/ui/impl-trait/region-escape-via-bound.rs
+++ b/src/test/ui/impl-trait/region-escape-via-bound.rs
@@ -24,7 +24,7 @@
 impl Trait<'b> for Cell<&'a u32> { }
 
 fn foo(x: Cell<&'x u32>) -> impl Trait<'y>
-    //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds [E0909]
+    //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds [E0700]
 where 'x: 'y
 {
     x
diff --git a/src/test/ui/impl-trait/region-escape-via-bound.stderr b/src/test/ui/impl-trait/region-escape-via-bound.stderr
index 4281a4c..b673111 100644
--- a/src/test/ui/impl-trait/region-escape-via-bound.stderr
+++ b/src/test/ui/impl-trait/region-escape-via-bound.stderr
@@ -1,4 +1,4 @@
-error[E0909]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
   --> $DIR/region-escape-via-bound.rs:26:29
    |
 LL | fn foo(x: Cell<&'x u32>) -> impl Trait<'y>
@@ -8,7 +8,7 @@
   --> $DIR/region-escape-via-bound.rs:26:1
    |
 LL | / fn foo(x: Cell<&'x u32>) -> impl Trait<'y>
-LL | |     //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds [E0909]
+LL | |     //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds [E0700]
 LL | | where 'x: 'y
 LL | | {
 LL | |     x
@@ -17,4 +17,4 @@
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0909`.
+For more information about this error, try `rustc --explain E0700`.
diff --git a/src/test/ui/infinite-recursion-const-fn.rs b/src/test/ui/infinite-recursion-const-fn.rs
index f98074b..4f1f672 100644
--- a/src/test/ui/infinite-recursion-const-fn.rs
+++ b/src/test/ui/infinite-recursion-const-fn.rs
@@ -11,8 +11,8 @@
 //https://github.com/rust-lang/rust/issues/31364
 
 #![feature(const_fn)]
-const fn a() -> usize { b() } //~ ERROR constant evaluation error
+const fn a() -> usize { b() }
 const fn b() -> usize { a() }
-const ARR: [i32; a()] = [5; 6];
+const ARR: [i32; a()] = [5; 6]; //~ ERROR could not evaluate constant expression
 
 fn main(){}
diff --git a/src/test/ui/infinite-recursion-const-fn.stderr b/src/test/ui/infinite-recursion-const-fn.stderr
index 81717fe..fb7c1be 100644
--- a/src/test/ui/infinite-recursion-const-fn.stderr
+++ b/src/test/ui/infinite-recursion-const-fn.stderr
@@ -1,8 +1,8 @@
-error[E0080]: constant evaluation error
-  --> $DIR/infinite-recursion-const-fn.rs:14:25
+error[E0080]: could not evaluate constant expression
+  --> $DIR/infinite-recursion-const-fn.rs:16:1
    |
-LL | const fn a() -> usize { b() } //~ ERROR constant evaluation error
-   |                         ^^^
+LL | const fn a() -> usize { b() }
+   |                         ---
    |                         |
    |                         reached the configured maximum number of stack frames
    |                         inside call to `b`
@@ -58,14 +58,10 @@
    |                         inside call to `a`
    |                         inside call to `a`
    |                         inside call to `a`
-LL | const ARR: [i32; a()] = [5; 6];
-   |                  --- inside call to `a`
-   |
-note: for constant expression here
-  --> $DIR/infinite-recursion-const-fn.rs:16:1
-   |
-LL | const ARR: [i32; a()] = [5; 6];
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | const ARR: [i32; a()] = [5; 6]; //~ ERROR could not evaluate constant expression
+   | ^^^^^^^^^^^^^^^^^---^^^^^^^^^^^
+   |                  |
+   |                  inside call to `a`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issue-23217.stderr b/src/test/ui/issue-23217.stderr
index d542a10..d87f239 100644
--- a/src/test/ui/issue-23217.stderr
+++ b/src/test/ui/issue-23217.stderr
@@ -6,7 +6,7 @@
 LL |     B = SomeEnum::A,
    |         ^^^^^^^^^^^ variant not found in `SomeEnum`
    |
-   = note: did you mean `variant::B`?
+   = note: did you mean `SomeEnum::B`?
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issue-28971.stderr b/src/test/ui/issue-28971.stderr
index df11435..c04e21f 100644
--- a/src/test/ui/issue-28971.stderr
+++ b/src/test/ui/issue-28971.stderr
@@ -7,7 +7,7 @@
 LL |             Foo::Baz(..) => (),
    |             ^^^^^^^^^^^^ variant not found in `Foo`
    |
-   = note: did you mean `variant::Bar`?
+   = note: did you mean `Foo::Bar`?
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/feature-gate-global_allocator.rs b/src/test/ui/issue-38715.rs
similarity index 67%
copy from src/test/ui/feature-gate-global_allocator.rs
copy to src/test/ui/issue-38715.rs
index ff3c342..552653c 100644
--- a/src/test/ui/feature-gate-global_allocator.rs
+++ b/src/test/ui/issue-38715.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#[global_allocator] //~ ERROR: attribute is an experimental feature
-static A: usize = 0;
+#[macro_export]
+macro_rules! foo { ($i:ident) => {} }
 
-fn main() {}
+#[macro_export]
+macro_rules! foo { () => {} } //~ ERROR a macro named `foo` has already been exported
+                              //~| WARN this was previously accepted
diff --git a/src/test/ui/issue-38715.stderr b/src/test/ui/issue-38715.stderr
new file mode 100644
index 0000000..a0dbcbd
--- /dev/null
+++ b/src/test/ui/issue-38715.stderr
@@ -0,0 +1,22 @@
+error: a macro named `foo` has already been exported
+  --> $DIR/issue-38715.rs:15:1
+   |
+LL | macro_rules! foo { () => {} } //~ ERROR a macro named `foo` has already been exported
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `foo` already exported
+   |
+   = note: #[deny(duplicate_macro_exports)] on by default
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
+   = note: for more information, see issue #35896 <https://github.com/rust-lang/rust/issues/35896>
+note: previous macro export is now shadowed
+  --> $DIR/issue-38715.rs:12:1
+   |
+LL | macro_rules! foo { ($i:ident) => {} }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0601]: `main` function not found in crate `issue_38715`
+   |
+   = note: consider adding a `main` function to `$DIR/issue-38715.rs`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/issue-45697.nll.stderr b/src/test/ui/issue-45697.nll.stderr
deleted file mode 100644
index a85972f..0000000
--- a/src/test/ui/issue-45697.nll.stderr
+++ /dev/null
@@ -1,34 +0,0 @@
-error[E0506]: cannot assign to `*y.pointer` because it is borrowed (Ast)
-  --> $DIR/issue-45697.rs:30:9
-   |
-LL |         let z = copy_borrowed_ptr(&mut y);
-   |                                        - borrow of `*y.pointer` occurs here
-LL |         *y.pointer += 1;
-   |         ^^^^^^^^^^^^^^^ assignment to borrowed `*y.pointer` occurs here
-
-error[E0503]: cannot use `*y.pointer` because it was mutably borrowed (Mir)
-  --> $DIR/issue-45697.rs:30:9
-   |
-LL |         let z = copy_borrowed_ptr(&mut y);
-   |                                   ------ borrow of `y` occurs here
-LL |         *y.pointer += 1;
-   |         ^^^^^^^^^^^^^^^ use of borrowed `y`
-...
-LL |         *z.pointer += 1;
-   |         --------------- borrow later used here
-
-error[E0506]: cannot assign to `*y.pointer` because it is borrowed (Mir)
-  --> $DIR/issue-45697.rs:30:9
-   |
-LL |         let z = copy_borrowed_ptr(&mut y);
-   |                                   ------ borrow of `*y.pointer` occurs here
-LL |         *y.pointer += 1;
-   |         ^^^^^^^^^^^^^^^ assignment to borrowed `*y.pointer` occurs here
-...
-LL |         *z.pointer += 1;
-   |         --------------- borrow later used here
-
-error: aborting due to 3 previous errors
-
-Some errors occurred: E0503, E0506.
-For more information about an error, try `rustc --explain E0503`.
diff --git a/src/test/ui/issue-49257.rs b/src/test/ui/issue-49257.rs
index a319849..f288a2b 100644
--- a/src/test/ui/issue-49257.rs
+++ b/src/test/ui/issue-49257.rs
@@ -17,6 +17,8 @@
 
 fn main() {
     let p = Point { x: 0, y: 0 };
+    let Point { .., y, } = p; //~ ERROR expected `}`, found `,`
     let Point { .., y } = p; //~ ERROR expected `}`, found `,`
-    //~| ERROR pattern does not mention fields `x`, `y`
+    let Point { .., } = p; //~ ERROR expected `}`, found `,`
+    let Point { .. } = p;
 }
diff --git a/src/test/ui/issue-49257.stderr b/src/test/ui/issue-49257.stderr
index fec9907..4017983 100644
--- a/src/test/ui/issue-49257.stderr
+++ b/src/test/ui/issue-49257.stderr
@@ -1,15 +1,38 @@
 error: expected `}`, found `,`
   --> $DIR/issue-49257.rs:20:19
    |
-LL |     let Point { .., y } = p; //~ ERROR expected `}`, found `,`
-   |                   ^ `..` must be in the last position, and cannot have a trailing comma
+LL |     let Point { .., y, } = p; //~ ERROR expected `}`, found `,`
+   |                 --^
+   |                 | |
+   |                 | expected `}`
+   |                 `..` must be at the end and cannot have a trailing comma
+help: move the `..` to the end of the field list
+   |
+LL |     let Point {  y, .. } = p; //~ ERROR expected `}`, found `,`
+   |                --   ^^^^
 
-error[E0027]: pattern does not mention fields `x`, `y`
-  --> $DIR/issue-49257.rs:20:9
+error: expected `}`, found `,`
+  --> $DIR/issue-49257.rs:21:19
    |
 LL |     let Point { .., y } = p; //~ ERROR expected `}`, found `,`
-   |         ^^^^^^^^^^^^^^^ missing fields `x`, `y`
+   |                 --^
+   |                 | |
+   |                 | expected `}`
+   |                 `..` must be at the end and cannot have a trailing comma
+help: move the `..` to the end of the field list
+   |
+LL |     let Point {  y , .. } = p; //~ ERROR expected `}`, found `,`
+   |                --  ^^^^^^
 
-error: aborting due to 2 previous errors
+error: expected `}`, found `,`
+  --> $DIR/issue-49257.rs:22:19
+   |
+LL |     let Point { .., } = p; //~ ERROR expected `}`, found `,`
+   |                 --^
+   |                 | |
+   |                 | expected `}`
+   |                 | help: remove this comma
+   |                 `..` must be at the end and cannot have a trailing comma
 
-For more information about this error, try `rustc --explain E0027`.
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/issue-50825-1.rs b/src/test/ui/issue-50825-1.rs
index d179530..1eee9b7 100644
--- a/src/test/ui/issue-50825-1.rs
+++ b/src/test/ui/issue-50825-1.rs
@@ -10,7 +10,7 @@
 
 // run-pass
 // regression test for issue #50825
-// Make sure that the `impl` bound (): X<T = ()> is prefered over
+// Make sure that the `impl` bound (): X<T = ()> is preferred over
 // the (): X bound in the where clause.
 
 trait X {
diff --git a/src/test/ui/issue-50825.rs b/src/test/ui/issue-50825.rs
index bc15760..e45156b 100644
--- a/src/test/ui/issue-50825.rs
+++ b/src/test/ui/issue-50825.rs
@@ -10,7 +10,7 @@
 
 // run-pass
 // regression test for issue #50825
-// Make sure that the built-in bound {integer}: Sized is prefered over
+// Make sure that the built-in bound {integer}: Sized is preferred over
 // the u64: Sized bound in the where clause.
 
 fn foo(y: &[()])
diff --git a/src/test/ui/issue-51044.rs b/src/test/ui/issue-51044.rs
new file mode 100644
index 0000000..6424c42
--- /dev/null
+++ b/src/test/ui/issue-51044.rs
@@ -0,0 +1,40 @@
+// Copyright 2018 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.
+
+// run-pass
+// regression test for issue #50825
+// Check that the feature gate normalizes associated types.
+
+#![allow(dead_code)]
+struct Foo<T>(T);
+struct Duck;
+struct Quack;
+
+trait Hello<A> where A: Animal {
+}
+
+trait Animal {
+    type Noise;
+}
+
+trait Loud<R>  {
+}
+
+impl Loud<Quack> for f32 {
+}
+
+impl Animal for Duck {
+    type Noise = Quack;
+}
+
+impl Hello<Duck> for Foo<f32> where f32: Loud<<Duck as Animal>::Noise> {
+}
+
+fn main() {}
diff --git a/src/test/ui/issue-51279.rs b/src/test/ui/issue-51279.rs
new file mode 100644
index 0000000..4639d73
--- /dev/null
+++ b/src/test/ui/issue-51279.rs
@@ -0,0 +1,34 @@
+// Copyright 2018 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 X<#[cfg(none)] 'a, #[cfg(none)] T>(&'a T);
+//~^ ERROR #[cfg] cannot be applied on a generic parameter
+//~^^ ERROR #[cfg] cannot be applied on a generic parameter
+
+impl<#[cfg(none)] 'a, #[cfg(none)] T> X<'a, T> {}
+//~^ ERROR #[cfg] cannot be applied on a generic parameter
+//~^^ ERROR #[cfg] cannot be applied on a generic parameter
+
+pub fn f<#[cfg(none)] 'a, #[cfg(none)] T>(_: &'a T) {}
+//~^ ERROR #[cfg] cannot be applied on a generic parameter
+//~^^ ERROR #[cfg] cannot be applied on a generic parameter
+
+#[cfg(none)]
+pub struct Y<#[cfg(none)] T>(T); // shouldn't care when the entire item is stripped out
+
+struct M<T>(*const T);
+
+unsafe impl<#[cfg_attr(none, may_dangle)] T> Drop for M<T> {
+    //~^ ERROR #[cfg_attr] cannot be applied on a generic parameter
+    fn drop(&mut self) {}
+}
+
+type Z<#[ignored] 'a, #[cfg(none)] T> = X<'a, T>;
+//~^ ERROR #[cfg] cannot be applied on a generic parameter
diff --git a/src/test/ui/issue-51279.stderr b/src/test/ui/issue-51279.stderr
new file mode 100644
index 0000000..38d5a5a
--- /dev/null
+++ b/src/test/ui/issue-51279.stderr
@@ -0,0 +1,50 @@
+error: #[cfg] cannot be applied on a generic parameter
+  --> $DIR/issue-51279.rs:11:14
+   |
+LL | pub struct X<#[cfg(none)] 'a, #[cfg(none)] T>(&'a T);
+   |              ^^^^^^^^^^^^
+
+error: #[cfg] cannot be applied on a generic parameter
+  --> $DIR/issue-51279.rs:11:31
+   |
+LL | pub struct X<#[cfg(none)] 'a, #[cfg(none)] T>(&'a T);
+   |                               ^^^^^^^^^^^^
+
+error: #[cfg] cannot be applied on a generic parameter
+  --> $DIR/issue-51279.rs:15:6
+   |
+LL | impl<#[cfg(none)] 'a, #[cfg(none)] T> X<'a, T> {}
+   |      ^^^^^^^^^^^^
+
+error: #[cfg] cannot be applied on a generic parameter
+  --> $DIR/issue-51279.rs:15:23
+   |
+LL | impl<#[cfg(none)] 'a, #[cfg(none)] T> X<'a, T> {}
+   |                       ^^^^^^^^^^^^
+
+error: #[cfg] cannot be applied on a generic parameter
+  --> $DIR/issue-51279.rs:19:10
+   |
+LL | pub fn f<#[cfg(none)] 'a, #[cfg(none)] T>(_: &'a T) {}
+   |          ^^^^^^^^^^^^
+
+error: #[cfg] cannot be applied on a generic parameter
+  --> $DIR/issue-51279.rs:19:27
+   |
+LL | pub fn f<#[cfg(none)] 'a, #[cfg(none)] T>(_: &'a T) {}
+   |                           ^^^^^^^^^^^^
+
+error: #[cfg_attr] cannot be applied on a generic parameter
+  --> $DIR/issue-51279.rs:28:13
+   |
+LL | unsafe impl<#[cfg_attr(none, may_dangle)] T> Drop for M<T> {
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: #[cfg] cannot be applied on a generic parameter
+  --> $DIR/issue-51279.rs:33:23
+   |
+LL | type Z<#[ignored] 'a, #[cfg(none)] T> = X<'a, T>;
+   |                       ^^^^^^^^^^^^
+
+error: aborting due to 8 previous errors
+
diff --git a/src/test/ui/lint-ctypes.rs b/src/test/ui/lint-ctypes.rs
index 8595783..4b20001 100644
--- a/src/test/ui/lint-ctypes.rs
+++ b/src/test/ui/lint-ctypes.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #![deny(improper_ctypes)]
-#![feature(libc, repr_transparent)]
+#![feature(libc)]
 
 extern crate libc;
 
diff --git a/src/test/ui/macros/macro-at-most-once-rep-ambig.rs b/src/test/ui/macros/macro-at-most-once-rep-ambig.rs
index e25c3cc..a5660f8 100644
--- a/src/test/ui/macros/macro-at-most-once-rep-ambig.rs
+++ b/src/test/ui/macros/macro-at-most-once-rep-ambig.rs
@@ -8,26 +8,30 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// Tests the behavior of various Kleene operators in macros with respect to `?` terminals. In
-// particular, `?` in the position of a separator and of a Kleene operator is tested.
+// The logic for parsing Kleene operators in macros has a special case to disambiguate `?`.
+// Specifically, `$(pat)?` is the ZeroOrOne operator whereas `$(pat)?+` or `$(pat)?*` are the
+// ZeroOrMore and OneOrMore operators using `?` as a separator. These tests are intended to
+// exercise that logic in the macro parser.
+//
+// Moreover, we also throw in some tests for using a separator with `?`, which is meaningless but
+// included for consistency with `+` and `*`.
+//
+// This test focuses on error cases.
 
 #![feature(macro_at_most_once_rep)]
 
-// should match `` and `a`
 macro_rules! foo {
     ($(a)?) => {}
 }
 
 macro_rules! baz {
-    ($(a),?) => {} //~ ERROR `?` macro repetition does not allow a separator
+    ($(a),?) => {} // comma separator is meaningless for `?`
 }
 
-// should match `+` and `a+`
 macro_rules! barplus {
     ($(a)?+) => {}
 }
 
-// should match `*` and `a*`
 macro_rules! barstar {
     ($(a)?*) => {}
 }
@@ -36,14 +40,14 @@
     foo!(a?a?a); //~ ERROR no rules expected the token `?`
     foo!(a?a); //~ ERROR no rules expected the token `?`
     foo!(a?); //~ ERROR no rules expected the token `?`
+    baz!(a?a?a); //~ ERROR no rules expected the token `?`
+    baz!(a?a); //~ ERROR no rules expected the token `?`
+    baz!(a?); //~ ERROR no rules expected the token `?`
+    baz!(a,); //~ ERROR unexpected end of macro invocation
+    baz!(a?a?a,); //~ ERROR no rules expected the token `?`
+    baz!(a?a,); //~ ERROR no rules expected the token `?`
+    baz!(a?,); //~ ERROR no rules expected the token `?`
     barplus!(); //~ ERROR unexpected end of macro invocation
-    barstar!(); //~ ERROR unexpected end of macro invocation
-    barplus!(a?); //~ ERROR no rules expected the token `?`
-    barplus!(a); //~ ERROR unexpected end of macro invocation
-    barstar!(a?); //~ ERROR no rules expected the token `?`
-    barstar!(a); //~ ERROR unexpected end of macro invocation
-    barplus!(+); // ok
-    barstar!(*); // ok
-    barplus!(a+); // ok
-    barstar!(a*); // ok
+    barplus!(a?); //~ ERROR unexpected end of macro invocation
+    barstar!(a?); //~ ERROR unexpected end of macro invocation
 }
diff --git a/src/test/ui/macros/macro-at-most-once-rep-ambig.stderr b/src/test/ui/macros/macro-at-most-once-rep-ambig.stderr
index cb1e360..d382082 100644
--- a/src/test/ui/macros/macro-at-most-once-rep-ambig.stderr
+++ b/src/test/ui/macros/macro-at-most-once-rep-ambig.stderr
@@ -1,62 +1,80 @@
-error: `?` macro repetition does not allow a separator
-  --> $DIR/macro-at-most-once-rep-ambig.rs:22:10
-   |
-LL |     ($(a),?) => {} //~ ERROR `?` macro repetition does not allow a separator
-   |          ^
-
 error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-ambig.rs:36:11
+  --> $DIR/macro-at-most-once-rep-ambig.rs:40:11
    |
 LL |     foo!(a?a?a); //~ ERROR no rules expected the token `?`
    |           ^
 
 error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-ambig.rs:37:11
+  --> $DIR/macro-at-most-once-rep-ambig.rs:41:11
    |
 LL |     foo!(a?a); //~ ERROR no rules expected the token `?`
    |           ^
 
 error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-ambig.rs:38:11
+  --> $DIR/macro-at-most-once-rep-ambig.rs:42:11
    |
 LL |     foo!(a?); //~ ERROR no rules expected the token `?`
    |           ^
 
+error: no rules expected the token `?`
+  --> $DIR/macro-at-most-once-rep-ambig.rs:43:11
+   |
+LL |     baz!(a?a?a); //~ ERROR no rules expected the token `?`
+   |           ^
+
+error: no rules expected the token `?`
+  --> $DIR/macro-at-most-once-rep-ambig.rs:44:11
+   |
+LL |     baz!(a?a); //~ ERROR no rules expected the token `?`
+   |           ^
+
+error: no rules expected the token `?`
+  --> $DIR/macro-at-most-once-rep-ambig.rs:45:11
+   |
+LL |     baz!(a?); //~ ERROR no rules expected the token `?`
+   |           ^
+
 error: unexpected end of macro invocation
-  --> $DIR/macro-at-most-once-rep-ambig.rs:39:5
+  --> $DIR/macro-at-most-once-rep-ambig.rs:46:11
+   |
+LL |     baz!(a,); //~ ERROR unexpected end of macro invocation
+   |           ^
+
+error: no rules expected the token `?`
+  --> $DIR/macro-at-most-once-rep-ambig.rs:47:11
+   |
+LL |     baz!(a?a?a,); //~ ERROR no rules expected the token `?`
+   |           ^
+
+error: no rules expected the token `?`
+  --> $DIR/macro-at-most-once-rep-ambig.rs:48:11
+   |
+LL |     baz!(a?a,); //~ ERROR no rules expected the token `?`
+   |           ^
+
+error: no rules expected the token `?`
+  --> $DIR/macro-at-most-once-rep-ambig.rs:49:11
+   |
+LL |     baz!(a?,); //~ ERROR no rules expected the token `?`
+   |           ^
+
+error: unexpected end of macro invocation
+  --> $DIR/macro-at-most-once-rep-ambig.rs:50:5
    |
 LL |     barplus!(); //~ ERROR unexpected end of macro invocation
    |     ^^^^^^^^^^^
 
 error: unexpected end of macro invocation
-  --> $DIR/macro-at-most-once-rep-ambig.rs:40:5
+  --> $DIR/macro-at-most-once-rep-ambig.rs:51:15
    |
-LL |     barstar!(); //~ ERROR unexpected end of macro invocation
-   |     ^^^^^^^^^^^
-
-error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-ambig.rs:41:15
-   |
-LL |     barplus!(a?); //~ ERROR no rules expected the token `?`
+LL |     barplus!(a?); //~ ERROR unexpected end of macro invocation
    |               ^
 
 error: unexpected end of macro invocation
-  --> $DIR/macro-at-most-once-rep-ambig.rs:42:14
+  --> $DIR/macro-at-most-once-rep-ambig.rs:52:15
    |
-LL |     barplus!(a); //~ ERROR unexpected end of macro invocation
-   |              ^
-
-error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-ambig.rs:43:15
-   |
-LL |     barstar!(a?); //~ ERROR no rules expected the token `?`
+LL |     barstar!(a?); //~ ERROR unexpected end of macro invocation
    |               ^
 
-error: unexpected end of macro invocation
-  --> $DIR/macro-at-most-once-rep-ambig.rs:44:14
-   |
-LL |     barstar!(a); //~ ERROR unexpected end of macro invocation
-   |              ^
-
-error: aborting due to 10 previous errors
+error: aborting due to 13 previous errors
 
diff --git a/src/test/ui/maybe-bounds.rs b/src/test/ui/maybe-bounds.rs
index 1dc198d..ec8a6b8 100644
--- a/src/test/ui/maybe-bounds.rs
+++ b/src/test/ui/maybe-bounds.rs
@@ -10,7 +10,7 @@
 
 trait Tr: ?Sized {} //~ ERROR `?Trait` is not permitted in supertraits
 
-type A1 = Tr + ?Sized; //~ ERROR `?Trait` is not permitted in trait object types
-type A2 = for<'a> Tr + ?Sized; //~ ERROR `?Trait` is not permitted in trait object types
+type A1 = Tr + (?Sized); //~ ERROR `?Trait` is not permitted in trait object types
+type A2 = for<'a> Tr + (?Sized); //~ ERROR `?Trait` is not permitted in trait object types
 
 fn main() {}
diff --git a/src/test/ui/maybe-bounds.stderr b/src/test/ui/maybe-bounds.stderr
index 72f052b..db8f7ad 100644
--- a/src/test/ui/maybe-bounds.stderr
+++ b/src/test/ui/maybe-bounds.stderr
@@ -1,22 +1,22 @@
 error: `?Trait` is not permitted in supertraits
-  --> $DIR/maybe-bounds.rs:11:12
+  --> $DIR/maybe-bounds.rs:11:11
    |
 LL | trait Tr: ?Sized {} //~ ERROR `?Trait` is not permitted in supertraits
-   |            ^^^^^
+   |           ^^^^^^
    |
    = note: traits are `?Sized` by default
 
 error: `?Trait` is not permitted in trait object types
-  --> $DIR/maybe-bounds.rs:13:17
+  --> $DIR/maybe-bounds.rs:13:16
    |
-LL | type A1 = Tr + ?Sized; //~ ERROR `?Trait` is not permitted in trait object types
-   |                 ^^^^^
+LL | type A1 = Tr + (?Sized); //~ ERROR `?Trait` is not permitted in trait object types
+   |                ^^^^^^^^
 
 error: `?Trait` is not permitted in trait object types
-  --> $DIR/maybe-bounds.rs:14:25
+  --> $DIR/maybe-bounds.rs:14:24
    |
-LL | type A2 = for<'a> Tr + ?Sized; //~ ERROR `?Trait` is not permitted in trait object types
-   |                         ^^^^^
+LL | type A2 = for<'a> Tr + (?Sized); //~ ERROR `?Trait` is not permitted in trait object types
+   |                        ^^^^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
index a0ad8ee..067b5eb 100644
--- a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
@@ -18,7 +18,7 @@
    |
    = note: defining type: DefId(0/1:9 ~ escape_argument_callee[317d]::test[0]::{{closure}}[0]) with closure substs [
                i16,
-               for<'r, 's, 't0> extern "rust-call" fn((&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 'r)) mut &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 's)) i32, &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 't0)) i32))
+               for<'r, 's, 't0> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) mut &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) i32, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't0)) i32))
            ]
 
 note: No external requirements
diff --git a/src/test/ui/nll/closure-requirements/escape-argument.stderr b/src/test/ui/nll/closure-requirements/escape-argument.stderr
index 6aeb8d4..dba27f1 100644
--- a/src/test/ui/nll/closure-requirements/escape-argument.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-argument.stderr
@@ -6,7 +6,7 @@
    |
    = note: defining type: DefId(0/1:9 ~ escape_argument[317d]::test[0]::{{closure}}[0]) with closure substs [
                i16,
-               for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 'r)) mut &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 's)) i32, &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 's)) i32))
+               for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) mut &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) i32, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) i32))
            ]
 
 note: No external requirements
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
index 26ad522..c88f0ef 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
@@ -24,7 +24,7 @@
    |
    = note: defining type: DefId(0/1:20 ~ propagate_approximated_fail_no_postdom[317d]::supply[0]::{{closure}}[0]) with closure substs [
                i16,
-               for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 's)) &'_#3r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>))
+               for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) &'_#3r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>))
            ]
 
 note: No external requirements
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
index 537e951..840b407 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
@@ -18,7 +18,7 @@
    |
    = note: defining type: DefId(0/1:18 ~ propagate_approximated_ref[317d]::supply[0]::{{closure}}[0]) with closure substs [
                i16,
-               for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 't1)) &'_#2r u32>, &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 't3)) std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 't1)) u32>))
+               for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't3)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) u32>))
            ]
    = note: number of external vids: 3
    = note: where '_#1r: '_#2r
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
index 93ae534..ac4efec 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
@@ -23,7 +23,7 @@
    |
    = note: defining type: DefId(0/1:12 ~ propagate_approximated_shorter_to_static_comparing_against_free[317d]::case1[0]::{{closure}}[0]) with closure substs [
                i32,
-               for<'r> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 'r)) u32>))
+               for<'r> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>))
            ]
 
 note: No external requirements
@@ -51,7 +51,7 @@
    |
    = note: defining type: DefId(0/1:13 ~ propagate_approximated_shorter_to_static_comparing_against_free[317d]::case2[0]::{{closure}}[0]) with closure substs [
                i32,
-               for<'r> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 'r)) u32>))
+               for<'r> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>))
            ]
    = note: number of external vids: 2
    = note: where '_#1r: '_#0r
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
index 4081ec6..93a7c1a 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
@@ -18,22 +18,21 @@
    |
    = note: defining type: DefId(0/1:18 ~ propagate_approximated_shorter_to_static_no_bound[317d]::supply[0]::{{closure}}[0]) with closure substs [
                i16,
-               for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 't1)) std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 't2)) u32>))
+               for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't2)) u32>))
            ]
    = note: number of external vids: 2
    = note: where '_#1r: '_#0r
 
 error: free region `ReFree(DefId(0/0:6 ~ propagate_approximated_shorter_to_static_no_bound[317d]::supply[0]), BrNamed(crate0:DefIndex(1:16), 'a))` does not outlive free region `ReStatic`
-  --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:45:47
+  --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:45:5
    |
-LL |       establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
-   |  _______________________________________________^
+LL | /     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
 LL | |         //~^ ERROR does not outlive free region
 LL | |
 LL | |         // Only works if 'x: 'y:
 LL | |         demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll
 LL | |     });
-   | |_____^
+   | |______^
 
 note: No external requirements
   --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:44:1
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
index 7a745bb..c62f62e 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
@@ -18,22 +18,21 @@
    |
    = note: defining type: DefId(0/1:18 ~ propagate_approximated_shorter_to_static_wrong_bound[317d]::supply[0]::{{closure}}[0]) with closure substs [
                i16,
-               for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 't1)) u32>, &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 't3)) std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 't1)) u32>))
+               for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't3)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) u32>))
            ]
    = note: number of external vids: 3
    = note: where '_#1r: '_#0r
 
 error: free region `ReFree(DefId(0/0:6 ~ propagate_approximated_shorter_to_static_wrong_bound[317d]::supply[0]), BrNamed(crate0:DefIndex(1:16), 'a))` does not outlive free region `ReStatic`
-  --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:48:47
+  --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:48:5
    |
-LL |       establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
-   |  _______________________________________________^
+LL | /     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
 LL | |         //~^ ERROR does not outlive free region
 LL | |         // Only works if 'x: 'y:
 LL | |         demand_y(x, y, x.get())
 LL | |         //~^ WARNING not reporting region error due to nll
 LL | |     });
-   | |_____^
+   | |______^
 
 note: No external requirements
   --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:47:1
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
index 4e26805..cf5f4d4 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
@@ -18,7 +18,7 @@
    |
    = note: defining type: DefId(0/1:18 ~ propagate_approximated_val[317d]::test[0]::{{closure}}[0]) with closure substs [
                i16,
-               for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 's)) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>))
+               for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>))
            ]
    = note: number of external vids: 3
    = note: where '_#1r: '_#2r
diff --git a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr
index 2cc9a11..ef27218 100644
--- a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr
@@ -16,7 +16,7 @@
    |
    = note: defining type: DefId(0/1:16 ~ propagate_despite_same_free_region[317d]::supply[0]::{{closure}}[0]) with closure substs [
                i16,
-               for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 's)) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>))
+               for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>))
            ]
    = note: number of external vids: 3
    = note: where '_#1r: '_#2r
diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
index e53ece6..8b6cd2e 100644
--- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
@@ -24,7 +24,7 @@
    |
    = note: defining type: DefId(0/1:18 ~ propagate_fail_to_approximate_longer_no_bounds[317d]::supply[0]::{{closure}}[0]) with closure substs [
                i16,
-               for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 's)) &'_#1r u32>, &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 't1)) u32>, &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>))
+               for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>))
            ]
 
 note: No external requirements
diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
index 45f308b..2fd6ce5 100644
--- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
@@ -24,7 +24,7 @@
    |
    = note: defining type: DefId(0/1:18 ~ propagate_fail_to_approximate_longer_wrong_bounds[317d]::supply[0]::{{closure}}[0]) with closure substs [
                i16,
-               for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 's)) &'_#1r u32>, &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 't1)) &'_#2r u32>, &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 't3)) std::cell::Cell<&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 't1)) u32>))
+               for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't3)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 't1)) u32>))
            ]
 
 note: No external requirements
diff --git a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
index 9e6fd28..04ff4aa 100644
--- a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
+++ b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
@@ -18,7 +18,7 @@
    |
    = note: defining type: DefId(0/1:9 ~ return_wrong_bound_region[317d]::test[0]::{{closure}}[0]) with closure substs [
                i16,
-               for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 'r)) i32, &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 's)) i32)) -> &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 'r)) i32
+               for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) i32, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) i32)) -> &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) i32
            ]
 
 note: No external requirements
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
index 70bda0d..0ada3fb 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
@@ -25,7 +25,7 @@
    = note: defining type: DefId(0/1:14 ~ ty_param_closure_approximate_lower_bound[317d]::generic[0]::{{closure}}[0]) with closure substs [
                T,
                i16,
-               for<'r, 's> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 'r)) ()>>, &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 's)) T))
+               for<'r, 's> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) ()>>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) T))
            ]
    = note: number of external vids: 2
    = note: where T: '_#1r
@@ -55,7 +55,7 @@
    = note: defining type: DefId(0/1:17 ~ ty_param_closure_approximate_lower_bound[317d]::generic_fail[0]::{{closure}}[0]) with closure substs [
                T,
                i16,
-               for<'r, 's> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 'r)) ()>>, &ReLateBound(DebruijnIndex { index: 0 }, BrNamed(crate0:DefIndex(0:0), 's)) T))
+               for<'r, 's> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 'r)) ()>>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0:0), 's)) T))
            ]
    = note: number of external vids: 2
    = note: where T: '_#1r
diff --git a/src/test/ui/resolve/token-error-correct-3.stderr b/src/test/ui/resolve/token-error-correct-3.stderr
index 284acd2..24186d9 100644
--- a/src/test/ui/resolve/token-error-correct-3.stderr
+++ b/src/test/ui/resolve/token-error-correct-3.stderr
@@ -10,11 +10,11 @@
 LL |             callback(path.as_ref(); //~ ERROR expected one of
    |                     ^
 
-error: expected one of `,`, `.`, `?`, or an operator, found `;`
+error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;`
   --> $DIR/token-error-correct-3.rs:24:35
    |
 LL |             callback(path.as_ref(); //~ ERROR expected one of
-   |                                   ^ expected one of `,`, `.`, `?`, or an operator here
+   |                                   ^ expected one of `)`, `,`, `.`, `?`, or an operator here
 
 error: expected one of `.`, `;`, `?`, `}`, or an operator, found `)`
   --> $DIR/token-error-correct-3.rs:30:9
diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test-should-panic.rs b/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test-should-panic.rs
index 73a0150..a0b2784 100644
--- a/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test-should-panic.rs
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test-should-panic.rs
@@ -10,7 +10,6 @@
 
 // compile-flags: --test
 
-#![feature(termination_trait_test)]
 #![feature(test)]
 
 extern crate test;
diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test-should-panic.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test-should-panic.stderr
index e3dab82..bfdcf01 100644
--- a/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test-should-panic.stderr
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test-should-panic.stderr
@@ -1,5 +1,5 @@
 error: functions using `#[should_panic]` must return `()`
-  --> $DIR/termination-trait-in-test-should-panic.rs:22:1
+  --> $DIR/termination-trait-in-test-should-panic.rs:21:1
    |
 LL | / fn not_a_num() -> Result<(), ParseIntError> {
 LL | |     //~^ ERROR functions using `#[should_panic]` must return `()`
diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test.rs b/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test.rs
index 2cb4552..0561b12 100644
--- a/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test.rs
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test.rs
@@ -11,7 +11,6 @@
 // compile-flags: --test
 // run-pass
 
-#![feature(termination_trait_test)]
 #![feature(test)]
 
 extern crate test;
diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs
index 1c00ede..6153d84 100644
--- a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs
@@ -10,8 +10,6 @@
 
 // compile-flags: --test
 
-#![feature(termination_trait_test)]
-
 use std::num::ParseIntError;
 
 #[test]
diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
index 8efd8a2..0972a09 100644
--- a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `main` has invalid return type `std::result::Result<f32, std::num::ParseIntError>`
-  --> $DIR/termination-trait-test-wrong-type.rs:18:1
+  --> $DIR/termination-trait-test-wrong-type.rs:16:1
    |
 LL | / fn can_parse_zero_as_f32() -> Result<f32, ParseIntError> { //~ ERROR
 LL | |     "0".parse()
diff --git a/src/test/ui/rfc-2166-underscore-imports/basic.stderr b/src/test/ui/rfc-2166-underscore-imports/basic.stderr
index 4530d0f..c12c74b 100644
--- a/src/test/ui/rfc-2166-underscore-imports/basic.stderr
+++ b/src/test/ui/rfc-2166-underscore-imports/basic.stderr
@@ -20,7 +20,7 @@
   --> $DIR/basic.rs:33:5
    |
 LL |     extern crate core as _; //~ WARN unused extern crate
-   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
    |
 note: lint level defined here
   --> $DIR/basic.rs:14:25
diff --git a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed
new file mode 100644
index 0000000..4f99c12
--- /dev/null
+++ b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed
@@ -0,0 +1,36 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:edition-lint-paths.rs
+// run-rustfix
+// compile-flags:--edition 2018
+
+// The "normal case". Ideally we would remove the `extern crate` here,
+// but we don't.
+
+#![feature(rust_2018_preview)]
+#![deny(rust_2018_idioms)]
+#![allow(dead_code)]
+
+
+//~^ ERROR unused extern crate
+
+use edition_lint_paths as bar;
+//~^ ERROR `extern crate` is not idiomatic in the new edition
+
+fn main() {
+    // This is not considered to *use* the `extern crate` in Rust 2018:
+    use edition_lint_paths::foo;
+    foo();
+
+    // But this should be a use of the (renamed) crate:
+    crate::bar::foo();
+}
+
diff --git a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs
new file mode 100644
index 0000000..9c1235a
--- /dev/null
+++ b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs
@@ -0,0 +1,36 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:edition-lint-paths.rs
+// run-rustfix
+// compile-flags:--edition 2018
+
+// The "normal case". Ideally we would remove the `extern crate` here,
+// but we don't.
+
+#![feature(rust_2018_preview)]
+#![deny(rust_2018_idioms)]
+#![allow(dead_code)]
+
+extern crate edition_lint_paths;
+//~^ ERROR unused extern crate
+
+extern crate edition_lint_paths as bar;
+//~^ ERROR `extern crate` is not idiomatic in the new edition
+
+fn main() {
+    // This is not considered to *use* the `extern crate` in Rust 2018:
+    use edition_lint_paths::foo;
+    foo();
+
+    // But this should be a use of the (renamed) crate:
+    crate::bar::foo();
+}
+
diff --git a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr
new file mode 100644
index 0000000..b3afa2b
--- /dev/null
+++ b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr
@@ -0,0 +1,21 @@
+error: unused extern crate
+  --> $DIR/extern-crate-idiomatic-in-2018.rs:22:1
+   |
+LL | extern crate edition_lint_paths;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
+   |
+note: lint level defined here
+  --> $DIR/extern-crate-idiomatic-in-2018.rs:19:9
+   |
+LL | #![deny(rust_2018_idioms)]
+   |         ^^^^^^^^^^^^^^^^
+   = note: #[deny(unused_extern_crates)] implied by #[deny(rust_2018_idioms)]
+
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/extern-crate-idiomatic-in-2018.rs:25:1
+   |
+LL | extern crate edition_lint_paths as bar;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/similar-tokens.rs b/src/test/ui/similar-tokens.rs
index eb7eab9..350a226 100644
--- a/src/test/ui/similar-tokens.rs
+++ b/src/test/ui/similar-tokens.rs
@@ -14,6 +14,6 @@
 }
 
 // `.` is similar to `,` so list parsing should continue to closing `}`
-use x::{A. B}; //~ ERROR expected one of `,`, `::`, or `as`, found `.`
+use x::{A. B}; //~ ERROR expected one of `,`, `::`, `as`, or `}`, found `.`
 
 fn main() {}
diff --git a/src/test/ui/similar-tokens.stderr b/src/test/ui/similar-tokens.stderr
index fe157b9..90acc56 100644
--- a/src/test/ui/similar-tokens.stderr
+++ b/src/test/ui/similar-tokens.stderr
@@ -1,8 +1,8 @@
-error: expected one of `,`, `::`, or `as`, found `.`
+error: expected one of `,`, `::`, `as`, or `}`, found `.`
   --> $DIR/similar-tokens.rs:17:10
    |
-LL | use x::{A. B}; //~ ERROR expected one of `,`, `::`, or `as`, found `.`
-   |          ^ expected one of `,`, `::`, or `as` here
+LL | use x::{A. B}; //~ ERROR expected one of `,`, `::`, `as`, or `}`, found `.`
+   |          ^ expected one of `,`, `::`, `as`, or `}` here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/span/issue-7575.stderr b/src/test/ui/span/issue-7575.stderr
index dc2cd4c..e31134f 100644
--- a/src/test/ui/span/issue-7575.stderr
+++ b/src/test/ui/span/issue-7575.stderr
@@ -2,10 +2,9 @@
   --> $DIR/issue-7575.rs:74:18
    |
 LL |     u.f8(42) + u.f9(342) + m.fff(42)
-   |                  ^^
+   |                  ^^ this is an associated function, not a method
    |
    = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
-   = help: try with `usize::f9`
 note: candidate #1 is defined in the trait `CtxtFn`
   --> $DIR/issue-7575.rs:16:5
    |
@@ -37,11 +36,13 @@
    | ---------------------- method `fff` not found for this
 ...
 LL |     u.f8(42) + u.f9(342) + m.fff(42)
-   |                              ^^^
+   |                            --^^^
+   |                            | |
+   |                            | this is an associated function, not a method
+   |                            help: use associated function syntax instead: `Myisize::fff`
    |
    = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
-   = help: try with `Myisize::fff`
-note: candidate #1 is defined in an impl for the type `Myisize`
+note: the candidate is defined in an impl for the type `Myisize`
   --> $DIR/issue-7575.rs:51:5
    |
 LL |     fn fff(i: isize) -> isize {
@@ -51,11 +52,10 @@
   --> $DIR/issue-7575.rs:82:7
    |
 LL |     t.is_str()
-   |       ^^^^^^
+   |       ^^^^^^ this is an associated function, not a method
    |
    = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
-   = help: try with `T::is_str`
-note: candidate #1 is defined in the trait `ManyImplTrait`
+note: the candidate is defined in the trait `ManyImplTrait`
   --> $DIR/issue-7575.rs:57:5
    |
 LL |     fn is_str() -> bool {
diff --git a/src/test/ui/suggestions/removing-extern-crate.fixed b/src/test/ui/suggestions/removing-extern-crate.fixed
index 723137f..83b35ce 100644
--- a/src/test/ui/suggestions/removing-extern-crate.fixed
+++ b/src/test/ui/suggestions/removing-extern-crate.fixed
@@ -16,12 +16,12 @@
 #![warn(rust_2018_idioms)]
 #![allow(unused_imports)]
 
-use std as foo;
+
 
 
 mod another {
-    use std as foo;
-    use std;
+    
+    
 }
 
 fn main() {}
diff --git a/src/test/ui/suggestions/removing-extern-crate.stderr b/src/test/ui/suggestions/removing-extern-crate.stderr
index 39d22de..f2eed27 100644
--- a/src/test/ui/suggestions/removing-extern-crate.stderr
+++ b/src/test/ui/suggestions/removing-extern-crate.stderr
@@ -1,31 +1,31 @@
-warning: `extern crate` is unnecessary in the new edition
+warning: unused extern crate
   --> $DIR/removing-extern-crate.rs:19:1
    |
 LL | extern crate std as foo;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `use`: `use std as foo;`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
    |
 note: lint level defined here
   --> $DIR/removing-extern-crate.rs:16:9
    |
 LL | #![warn(rust_2018_idioms)]
    |         ^^^^^^^^^^^^^^^^
-   = note: #[warn(unnecessary_extern_crates)] implied by #[warn(rust_2018_idioms)]
+   = note: #[warn(unused_extern_crates)] implied by #[warn(rust_2018_idioms)]
 
-warning: `extern crate` is unnecessary in the new edition
+warning: unused extern crate
   --> $DIR/removing-extern-crate.rs:20:1
    |
 LL | extern crate core;
    | ^^^^^^^^^^^^^^^^^^ help: remove it
 
-warning: `extern crate` is unnecessary in the new edition
+warning: unused extern crate
   --> $DIR/removing-extern-crate.rs:23:5
    |
 LL |     extern crate std as foo;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `use`: `use std as foo;`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
 
-warning: `extern crate` is unnecessary in the new edition
+warning: unused extern crate
   --> $DIR/removing-extern-crate.rs:24:5
    |
 LL |     extern crate std;
-   |     ^^^^^^^^^^^^^^^^^ help: use `use`: `use std;`
+   |     ^^^^^^^^^^^^^^^^^ help: remove it
 
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/ui/suggestions/repr.rs
similarity index 62%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/ui/suggestions/repr.rs
index e7ffbe8..312f602 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/ui/suggestions/repr.rs
@@ -8,7 +8,21 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
+// compile-pass
+
+#[repr]
+//^ WARN `repr` attribute must have a hint
+struct _A {}
+
+#[repr = "B"]
+//^ WARN `repr` attribute isn't configurable with a literal
+struct _B {}
+
+#[repr = "C"]
+//^ WARN `repr` attribute isn't configurable with a literal
+struct _C {}
+
+#[repr(C)]
+struct _D {}
 
 fn main() {}
diff --git a/src/test/ui/suggestions/repr.stderr b/src/test/ui/suggestions/repr.stderr
new file mode 100644
index 0000000..7a99d8c
--- /dev/null
+++ b/src/test/ui/suggestions/repr.stderr
@@ -0,0 +1,25 @@
+warning: `repr` attribute must have a hint
+  --> $DIR/repr.rs:13:1
+   |
+LL | #[repr]
+   | ^^^^^^^ needs a hint
+   |
+   = note: #[warn(bad_repr)] on by default
+   = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]`
+   = note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html>
+
+warning: `repr` attribute isn't configurable with a literal
+  --> $DIR/repr.rs:17:1
+   |
+LL | #[repr = "B"]
+   | ^^^^^^^^^^^^^ needs a hint
+   |
+   = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]`
+   = note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html>
+
+warning: `repr` attribute isn't configurable with a literal
+  --> $DIR/repr.rs:21:1
+   |
+LL | #[repr = "C"]
+   | ^^^^^^^^^^^^^ help: give `repr` a hint: `#[repr(C)]`
+
diff --git a/src/test/ui/target-feature-wrong.rs b/src/test/ui/target-feature-wrong.rs
index 0edd51b..8983c0e 100644
--- a/src/test/ui/target-feature-wrong.rs
+++ b/src/test/ui/target-feature-wrong.rs
@@ -14,7 +14,11 @@
 // ignore-emscripten
 // ignore-mips
 // ignore-powerpc
+// ignore-powerpc64
+// ignore-powerpc64le
 // ignore-s390x
+// ignore-sparc
+// ignore-sparc64
 
 #![feature(target_feature)]
 
diff --git a/src/test/ui/target-feature-wrong.stderr b/src/test/ui/target-feature-wrong.stderr
index ed86687..d4e1c97 100644
--- a/src/test/ui/target-feature-wrong.stderr
+++ b/src/test/ui/target-feature-wrong.stderr
@@ -1,35 +1,35 @@
 error: #[target_feature] attribute must be of the form #[target_feature(..)]
-  --> $DIR/target-feature-wrong.rs:21:1
+  --> $DIR/target-feature-wrong.rs:25:1
    |
 LL | #[target_feature = "+sse2"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: the feature named `foo` is not valid for this target
-  --> $DIR/target-feature-wrong.rs:23:18
+  --> $DIR/target-feature-wrong.rs:27:18
    |
 LL | #[target_feature(enable = "foo")]
    |                  ^^^^^^^^^^^^^^
 
 error: #[target_feature(..)] only accepts sub-keys of `enable` currently
-  --> $DIR/target-feature-wrong.rs:25:18
+  --> $DIR/target-feature-wrong.rs:29:18
    |
 LL | #[target_feature(bar)]
    |                  ^^^
 
 error: #[target_feature(..)] only accepts sub-keys of `enable` currently
-  --> $DIR/target-feature-wrong.rs:27:18
+  --> $DIR/target-feature-wrong.rs:31:18
    |
 LL | #[target_feature(disable = "baz")]
    |                  ^^^^^^^^^^^^^^^
 
 error: #[target_feature(..)] can only be applied to `unsafe` function
-  --> $DIR/target-feature-wrong.rs:31:1
+  --> $DIR/target-feature-wrong.rs:35:1
    |
 LL | #[target_feature(enable = "sse2")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: attribute should be applied to a function
-  --> $DIR/target-feature-wrong.rs:35:1
+  --> $DIR/target-feature-wrong.rs:39:1
    |
 LL | #[target_feature(enable = "sse2")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -38,7 +38,7 @@
    | -------------- not a function
 
 error: cannot use #[inline(always)] with #[target_feature]
-  --> $DIR/target-feature-wrong.rs:39:1
+  --> $DIR/target-feature-wrong.rs:43:1
    |
 LL | #[inline(always)]
    | ^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/token/issue-10636-2.stderr b/src/test/ui/token/issue-10636-2.stderr
index 56a3042..6c0053f 100644
--- a/src/test/ui/token/issue-10636-2.stderr
+++ b/src/test/ui/token/issue-10636-2.stderr
@@ -10,11 +10,11 @@
 LL |     option.map(|some| 42;
    |               ^
 
-error: expected one of `,`, `.`, `?`, or an operator, found `;`
+error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;`
   --> $DIR/issue-10636-2.rs:15:25
    |
 LL |     option.map(|some| 42;
-   |                         ^ expected one of `,`, `.`, `?`, or an operator here
+   |                         ^ expected one of `)`, `,`, `.`, `?`, or an operator here
 
 error: expected expression, found `)`
   --> $DIR/issue-10636-2.rs:18:1
diff --git a/src/test/ui/trait-object-auto-dedup-in-impl.rs b/src/test/ui/trait-object-auto-dedup-in-impl.rs
new file mode 100644
index 0000000..d3e4627
--- /dev/null
+++ b/src/test/ui/trait-object-auto-dedup-in-impl.rs
@@ -0,0 +1,29 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Checks to make sure that `dyn Trait + Send` and `dyn Trait + Send + Send` are the same type.
+// Issue: #47010
+
+struct Struct;
+impl Trait for Struct {}
+trait Trait {}
+
+type Send1 = Trait + Send;
+type Send2 = Trait + Send + Send;
+
+fn main () {}
+
+impl Trait + Send {
+    fn test(&self) { println!("one"); } //~ ERROR duplicate definitions with name `test`
+}
+
+impl Trait + Send + Send {
+    fn test(&self) { println!("two"); }
+}
diff --git a/src/test/ui/trait-object-auto-dedup-in-impl.stderr b/src/test/ui/trait-object-auto-dedup-in-impl.stderr
new file mode 100644
index 0000000..9abd81c
--- /dev/null
+++ b/src/test/ui/trait-object-auto-dedup-in-impl.stderr
@@ -0,0 +1,12 @@
+error[E0592]: duplicate definitions with name `test`
+  --> $DIR/trait-object-auto-dedup-in-impl.rs:24:5
+   |
+LL |     fn test(&self) { println!("one"); } //~ ERROR duplicate definitions with name `test`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definitions for `test`
+...
+LL |     fn test(&self) { println!("two"); }
+   |     ----------------------------------- other definition for `test`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0592`.
diff --git a/src/test/ui/trivial-bounds-inconsistent-associated-functions.rs b/src/test/ui/trivial-bounds-inconsistent-associated-functions.rs
index 4cacbc2..49c9df9 100644
--- a/src/test/ui/trivial-bounds-inconsistent-associated-functions.rs
+++ b/src/test/ui/trivial-bounds-inconsistent-associated-functions.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-test FIXME(#50825)
 // run-pass
 // Inconsistent bounds with trait implementations
 
diff --git a/src/test/ui/trivial-bounds-inconsistent-copy-reborrow.rs b/src/test/ui/trivial-bounds-inconsistent-copy-reborrow.rs
index a743b42..2c4d9d8 100644
--- a/src/test/ui/trivial-bounds-inconsistent-copy-reborrow.rs
+++ b/src/test/ui/trivial-bounds-inconsistent-copy-reborrow.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-test FIXME(#50825)
 // Check that reborrows are still illegal with Copy mutable references
 #![feature(trivial_bounds)]
 #![allow(unused)]
diff --git a/src/test/ui/trivial-bounds-inconsistent-copy.rs b/src/test/ui/trivial-bounds-inconsistent-copy.rs
index f73c96a..375885a 100644
--- a/src/test/ui/trivial-bounds-inconsistent-copy.rs
+++ b/src/test/ui/trivial-bounds-inconsistent-copy.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-test FIXME(#50825)
 // run-pass
 // Check tautalogically false `Copy` bounds
 #![feature(trivial_bounds)]
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/ui/trivial-bounds-inconsistent-projection-error.rs
similarity index 62%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/ui/trivial-bounds-inconsistent-projection-error.rs
index e7ffbe8..1a3bd3a 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/ui/trivial-bounds-inconsistent-projection-error.rs
@@ -8,7 +8,26 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
+#![feature(trivial_bounds)]
+#![allow(unused)]
 
-fn main() {}
+struct B;
+
+trait A {
+    type X;
+    fn get_x() -> Self::X;
+}
+
+impl A for B {
+    type X = u8;
+    fn get_x() -> u8 { 0 }
+}
+
+fn global_bound_is_hidden() -> u8
+where
+    B: A<X = i32>
+{
+    B::get_x() //~ ERROR
+}
+
+fn main () {}
diff --git a/src/test/ui/trivial-bounds-inconsistent-projection-error.stderr b/src/test/ui/trivial-bounds-inconsistent-projection-error.stderr
new file mode 100644
index 0000000..0f720be
--- /dev/null
+++ b/src/test/ui/trivial-bounds-inconsistent-projection-error.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+  --> $DIR/trivial-bounds-inconsistent-projection-error.rs:30:5
+   |
+LL | fn global_bound_is_hidden() -> u8
+   |                                -- expected `u8` because of return type
+...
+LL |     B::get_x() //~ ERROR
+   |     ^^^^^^^^^^ expected u8, found i32
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/trivial-bounds-inconsistent-projection.rs b/src/test/ui/trivial-bounds-inconsistent-projection.rs
new file mode 100644
index 0000000..8de6f06
--- /dev/null
+++ b/src/test/ui/trivial-bounds-inconsistent-projection.rs
@@ -0,0 +1,64 @@
+// Copyright 2018 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.
+
+// run-pass
+// Check that global bounds result in the expected choice of associated type
+
+#![feature(trivial_bounds)]
+#![allow(unused)]
+
+struct B;
+
+trait A {
+    type X;
+    fn get_x() -> Self::X;
+}
+
+impl A for B {
+    type X = u8;
+    fn get_x() -> u8 { 0 }
+}
+
+fn underspecified_bound() -> u8
+where
+    B: A
+{
+    B::get_x()
+}
+
+fn inconsistent_bound() -> i32
+where
+    B: A<X = i32>
+{
+    B::get_x()
+}
+
+fn redundant_bound() -> u8
+where
+    B: A<X = u8>
+{
+    B::get_x()
+}
+
+fn inconsistent_dup_bound() -> i32
+where
+    B: A<X = i32> + A
+{
+    B::get_x()
+}
+
+fn redundant_dup_bound() -> u8
+where
+    B: A<X = u8> + A
+{
+    B::get_x()
+}
+
+fn main () {}
diff --git a/src/test/ui/trivial-bounds-inconsistent-projection.stderr b/src/test/ui/trivial-bounds-inconsistent-projection.stderr
new file mode 100644
index 0000000..201a041
--- /dev/null
+++ b/src/test/ui/trivial-bounds-inconsistent-projection.stderr
@@ -0,0 +1,57 @@
+warning: Trait bound B: A does not depend on any type or lifetime parameters
+  --> $DIR/trivial-bounds-inconsistent-projection.rs:29:1
+   |
+LL | / fn underspecified_bound() -> u8
+LL | | where
+LL | |     B: A
+LL | | {
+LL | |     B::get_x()
+LL | | }
+   | |_^
+   |
+   = note: #[warn(trivial_bounds)] on by default
+
+warning: Trait bound B: A does not depend on any type or lifetime parameters
+  --> $DIR/trivial-bounds-inconsistent-projection.rs:36:1
+   |
+LL | / fn inconsistent_bound() -> i32
+LL | | where
+LL | |     B: A<X = i32>
+LL | | {
+LL | |     B::get_x()
+LL | | }
+   | |_^
+
+warning: Trait bound B: A does not depend on any type or lifetime parameters
+  --> $DIR/trivial-bounds-inconsistent-projection.rs:43:1
+   |
+LL | / fn redundant_bound() -> u8
+LL | | where
+LL | |     B: A<X = u8>
+LL | | {
+LL | |     B::get_x()
+LL | | }
+   | |_^
+
+warning: Trait bound B: A does not depend on any type or lifetime parameters
+  --> $DIR/trivial-bounds-inconsistent-projection.rs:50:1
+   |
+LL | / fn inconsistent_dup_bound() -> i32
+LL | | where
+LL | |     B: A<X = i32> + A
+LL | | {
+LL | |     B::get_x()
+LL | | }
+   | |_^
+
+warning: Trait bound B: A does not depend on any type or lifetime parameters
+  --> $DIR/trivial-bounds-inconsistent-projection.rs:57:1
+   |
+LL | / fn redundant_dup_bound() -> u8
+LL | | where
+LL | |     B: A<X = u8> + A
+LL | | {
+LL | |     B::get_x()
+LL | | }
+   | |_^
+
diff --git a/src/test/ui/trivial-bounds-inconsistent-sized.rs b/src/test/ui/trivial-bounds-inconsistent-sized.rs
index 11f0080..14ba11c 100644
--- a/src/test/ui/trivial-bounds-inconsistent-sized.rs
+++ b/src/test/ui/trivial-bounds-inconsistent-sized.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-test FIXME(#50825)
 // run-pass
 // Check tautalogically false `Sized` bounds
 #![feature(trivial_bounds)]
diff --git a/src/test/ui/trivial-bounds-inconsistent-well-formed.rs b/src/test/ui/trivial-bounds-inconsistent-well-formed.rs
index a78ecdc..5fcdbfc 100644
--- a/src/test/ui/trivial-bounds-inconsistent-well-formed.rs
+++ b/src/test/ui/trivial-bounds-inconsistent-well-formed.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-test FIXME(#50825)
 // run-pass
 // Test that inconsistent bounds are used in well-formedness checks
 #![feature(trivial_bounds)]
diff --git a/src/test/ui/trivial-bounds-inconsistent.rs b/src/test/ui/trivial-bounds-inconsistent.rs
index c8e8c32..2c8b873 100644
--- a/src/test/ui/trivial-bounds-inconsistent.rs
+++ b/src/test/ui/trivial-bounds-inconsistent.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-test FIXME(#50825)
 // run-pass
 
 // Check that tautalogically false bounds are accepted, and are used
diff --git a/src/test/ui/trivial-bounds-leak-copy.rs b/src/test/ui/trivial-bounds-leak-copy.rs
index 6f00000..9850ec2 100644
--- a/src/test/ui/trivial-bounds-leak-copy.rs
+++ b/src/test/ui/trivial-bounds-leak-copy.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-test FIXME(#50825)
 // Check that false Copy bounds don't leak
 #![feature(trivial_bounds)]
 
diff --git a/src/test/ui/trivial-bounds-leak.rs b/src/test/ui/trivial-bounds-leak.rs
index 15dee64..98cb5b2 100644
--- a/src/test/ui/trivial-bounds-leak.rs
+++ b/src/test/ui/trivial-bounds-leak.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-test FIXME(#50825)
 // Check that false bounds don't leak
 #![feature(trivial_bounds)]
 
diff --git a/src/test/ui/trivial-bounds-lint.rs b/src/test/ui/trivial-bounds-lint.rs
index e37600a..e6988cb 100644
--- a/src/test/ui/trivial-bounds-lint.rs
+++ b/src/test/ui/trivial-bounds-lint.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-test FIXME(#50825)
 #![feature(trivial_bounds)]
 #![allow(unused)]
 #![deny(trivial_bounds)]
diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/ui/trivial-bounds-object.rs
similarity index 60%
copy from src/test/ui/const-eval/index_out_of_bound.rs
copy to src/test/ui/trivial-bounds-object.rs
index e7ffbe8..00986ee 100644
--- a/src/test/ui/const-eval/index_out_of_bound.rs
+++ b/src/test/ui/trivial-bounds-object.rs
@@ -8,7 +8,21 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-static FOO: i32 = [][0];
-//~^ ERROR E0080
+// run-pass
+// Check that the object bound dyn A + 'a: A is preferred over the
+// where clause bound dyn A + 'static: A.
 
-fn main() {}
+#![allow(unused)]
+
+trait A {
+    fn test(&self);
+}
+
+fn foo(x: &dyn A)
+where
+    dyn A + 'static: A, // Using this bound would lead to a lifetime error.
+{
+    x.test();
+}
+
+fn main () {}
diff --git a/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test.rs b/src/test/ui/tuple-struct-fields/test.rs
similarity index 92%
rename from src/test/compile-fail/privacy/restricted/tuple-struct-fields/test.rs
rename to src/test/ui/tuple-struct-fields/test.rs
index d4ea76d..22d54a3 100644
--- a/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test.rs
+++ b/src/test/ui/tuple-struct-fields/test.rs
@@ -12,6 +12,6 @@
     type T = ();
     struct S1(pub(in foo) (), pub(T), pub(crate) (), pub(((), T)));
     struct S2(pub((foo)) ());
-    //~^ ERROR expected `,`, found `(`
+    //~^ ERROR expected one of `)` or `,`, found `(`
     //~| ERROR cannot find type `foo` in this scope
 }
diff --git a/src/test/ui/tuple-struct-fields/test.stderr b/src/test/ui/tuple-struct-fields/test.stderr
new file mode 100644
index 0000000..59228ea
--- /dev/null
+++ b/src/test/ui/tuple-struct-fields/test.stderr
@@ -0,0 +1,20 @@
+error: expected one of `)` or `,`, found `(`
+  --> $DIR/test.rs:14:26
+   |
+LL |     struct S2(pub((foo)) ());
+   |                          ^ expected one of `)` or `,` here
+
+error[E0412]: cannot find type `foo` in this scope
+  --> $DIR/test.rs:14:20
+   |
+LL |     struct S2(pub((foo)) ());
+   |                    ^^^ not found in this scope
+
+error[E0601]: `main` function not found in crate `test`
+   |
+   = note: consider adding a `main` function to `$DIR/test.rs`
+
+error: aborting due to 3 previous errors
+
+Some errors occurred: E0412, E0601.
+For more information about an error, try `rustc --explain E0412`.
diff --git a/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test2.rs b/src/test/ui/tuple-struct-fields/test2.rs
similarity index 91%
rename from src/test/compile-fail/privacy/restricted/tuple-struct-fields/test2.rs
rename to src/test/ui/tuple-struct-fields/test2.rs
index fed9432..eead027 100644
--- a/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test2.rs
+++ b/src/test/ui/tuple-struct-fields/test2.rs
@@ -13,7 +13,7 @@
         struct S1(pub $t);
         struct S2(pub (in foo) ());
         struct S3(pub $t ());
-        //~^ ERROR expected `,`, found `(`
+        //~^ ERROR expected one of `)` or `,`, found `(`
     }
 }
 
diff --git a/src/test/ui/tuple-struct-fields/test2.stderr b/src/test/ui/tuple-struct-fields/test2.stderr
new file mode 100644
index 0000000..983e747
--- /dev/null
+++ b/src/test/ui/tuple-struct-fields/test2.stderr
@@ -0,0 +1,11 @@
+error: expected one of `)` or `,`, found `(`
+  --> $DIR/test2.rs:15:26
+   |
+LL |         struct S3(pub $t ());
+   |                          ^ expected one of `)` or `,` here
+...
+LL |     define_struct! { (foo) }
+   |     ------------------------ in this macro invocation
+
+error: aborting due to previous error
+
diff --git a/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test3.rs b/src/test/ui/tuple-struct-fields/test3.rs
similarity index 91%
rename from src/test/compile-fail/privacy/restricted/tuple-struct-fields/test3.rs
rename to src/test/ui/tuple-struct-fields/test3.rs
index dd2cb0e..d666c8a 100644
--- a/src/test/compile-fail/privacy/restricted/tuple-struct-fields/test3.rs
+++ b/src/test/ui/tuple-struct-fields/test3.rs
@@ -13,7 +13,7 @@
         struct S1(pub($t));
         struct S2(pub (in foo) ());
         struct S3(pub($t) ());
-        //~^ ERROR expected `,`, found `(`
+        //~^ ERROR expected one of `)` or `,`, found `(`
     }
 }
 
diff --git a/src/test/ui/tuple-struct-fields/test3.stderr b/src/test/ui/tuple-struct-fields/test3.stderr
new file mode 100644
index 0000000..6738595
--- /dev/null
+++ b/src/test/ui/tuple-struct-fields/test3.stderr
@@ -0,0 +1,11 @@
+error: expected one of `)` or `,`, found `(`
+  --> $DIR/test3.rs:15:27
+   |
+LL |         struct S3(pub($t) ());
+   |                           ^ expected one of `)` or `,` here
+...
+LL |     define_struct! { foo }
+   |     ---------------------- in this macro invocation
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-dependent-def-issue-49241.rs b/src/test/ui/type-dependent-def-issue-49241.rs
index 6426499..db27ae8 100644
--- a/src/test/ui/type-dependent-def-issue-49241.rs
+++ b/src/test/ui/type-dependent-def-issue-49241.rs
@@ -11,5 +11,5 @@
 fn main() {
     let v = vec![0];
     const l: usize = v.count(); //~ ERROR can't capture dynamic environment in a fn item
-    let s: [u32; l] = v.into_iter().collect(); //~ ERROR constant evaluation error
+    let s: [u32; l] = v.into_iter().collect();
 }
diff --git a/src/test/ui/type-dependent-def-issue-49241.stderr b/src/test/ui/type-dependent-def-issue-49241.stderr
index f00edcc..361d28f 100644
--- a/src/test/ui/type-dependent-def-issue-49241.stderr
+++ b/src/test/ui/type-dependent-def-issue-49241.stderr
@@ -6,13 +6,6 @@
    |
    = help: use the `|| { ... }` closure form instead
 
-error[E0080]: constant evaluation error
-  --> $DIR/type-dependent-def-issue-49241.rs:14:18
-   |
-LL |     let s: [u32; l] = v.into_iter().collect(); //~ ERROR constant evaluation error
-   |                  ^ encountered constants with type errors, stopping evaluation
+error: aborting due to previous error
 
-error: aborting due to 2 previous errors
-
-Some errors occurred: E0080, E0434.
-For more information about an error, try `rustc --explain E0080`.
+For more information about this error, try `rustc --explain E0434`.
diff --git a/src/test/ui/update-all-references.sh b/src/test/ui/update-all-references.sh
deleted file mode 100755
index bfc6f92..0000000
--- a/src/test/ui/update-all-references.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-# A script to update the references for all tests. The idea is that
-# you do a run, which will generate files in the build directory
-# containing the (normalized) actual output of the compiler. You then
-# run this script, which will copy those files over. If you find
-# yourself manually editing a foo.stderr file, you're doing it wrong.
-#
-# See all `update-references.sh`, if you just want to update a single test.
-
-if [[ "$1" == "--help" || "$1" == "-h" || "$1" == "" || "$2" != "" ]]; then
-    echo "usage: $0 <build-directory>"
-    echo ""
-    echo "For example:"
-    echo "   $0 ../../../build/x86_64-apple-darwin/test/ui"
-fi
-
-BUILD_DIR=$PWD/$1
-MY_DIR=$(dirname $0)
-cd $MY_DIR
-find . -name '*.rs' | xargs ./update-references.sh $BUILD_DIR
diff --git a/src/test/ui/update-references.sh b/src/test/ui/update-references.sh
deleted file mode 100755
index f3c5997..0000000
--- a/src/test/ui/update-references.sh
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env bash
-#
-# 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.
-
-# A script to update the references for particular tests. The idea is
-# that you do a run, which will generate files in the build directory
-# containing the (normalized) actual output of the compiler. This
-# script will then copy that output and replace the "expected output"
-# files. You can then commit the changes.
-#
-# If you find yourself manually editing a foo.stderr file, you're
-# doing it wrong.
-
-if [[ "$1" == "--help" || "$1" == "-h" || "$1" == "" || "$2" == "" ]]; then
-    echo "usage: $0 <build-directory> <relative-path-to-rs-files>"
-    echo ""
-    echo "For example:"
-    echo "   $0 ../../../build/x86_64-apple-darwin/test/ui *.rs */*.rs"
-fi
-
-MYDIR=$(dirname $0)
-
-BUILD_DIR="$1"
-shift
-
-shopt -s nullglob
-
-while [[ "$1" != "" ]]; do
-    for EXT in "stderr" "stdout" "fixed"; do
-        for OUT_NAME in $BUILD_DIR/${1%.rs}*/*$EXT; do
-            OUT_DIR=`dirname "$1"`
-            OUT_BASE=`basename "$OUT_NAME"`
-            if ! (diff $OUT_NAME $MYDIR/$OUT_DIR/$OUT_BASE >& /dev/null); then
-                echo updating $MYDIR/$OUT_DIR/$OUT_BASE
-                cp $OUT_NAME $MYDIR/$OUT_DIR
-            fi
-        done
-    done
-    shift
-done
diff --git a/src/tools/cargo b/src/tools/cargo
index c3b09c9..e2348c2 160000
--- a/src/tools/cargo
+++ b/src/tools/cargo
@@ -1 +1 @@
-Subproject commit c3b09c9680fce8ab70a49c8531fd8f84c2ccdff2
+Subproject commit e2348c2db296ce33428933c3ab8786d5f3c54a2e
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 5daf192..caf73f4 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use common::CompareMode;
-use common::{expected_output_path, UI_FIXED, UI_STDERR, UI_STDOUT};
+use common::{expected_output_path, UI_EXTENSIONS, UI_FIXED, UI_STDERR, UI_STDOUT};
 use common::{output_base_dir, output_base_name, output_testname_unique};
 use common::{Codegen, CodegenUnits, DebugInfoGdb, DebugInfoLldb, Rustdoc};
 use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind};
@@ -2529,7 +2529,7 @@
                 .env("IS_WINDOWS", "1")
                 .env("MSVC_LIB", format!("'{}' -nologo", lib.display()))
                 .env("CC", format!("'{}' {}", self.config.cc, cflags))
-                .env("CXX", &self.config.cxx);
+                .env("CXX", format!("'{}'", &self.config.cxx));
         } else {
             cmd.env("CC", format!("{} {}", self.config.cc, self.config.cflags))
                 .env("CXX", format!("{} {}", self.config.cxx, self.config.cflags))
@@ -2609,6 +2609,9 @@
         errors += self.compare_output("stdout", &normalized_stdout, &expected_stdout);
         errors += self.compare_output("stderr", &normalized_stderr, &expected_stderr);
 
+        let modes_to_prune = vec![CompareMode::Nll];
+        self.prune_duplicate_outputs(&modes_to_prune);
+
         if self.config.compare_mode.is_some() {
             // don't test rustfix with nll right now
         } else if self.props.run_rustfix {
@@ -2971,6 +2974,16 @@
         }
     }
 
+    fn delete_file(&self, file: &PathBuf) {
+        if let Err(e) = ::std::fs::remove_file(file) {
+            self.fatal(&format!(
+                "failed to delete `{}`: {}",
+                file.display(),
+                e,
+            ));
+        }
+    }
+
     fn compare_output(&self, kind: &str, actual: &str, expected: &str) -> usize {
         if actual == expected {
             return 0;
@@ -3023,13 +3036,7 @@
 
         for output_file in &files {
             if actual.is_empty() {
-                if let Err(e) = ::std::fs::remove_file(output_file) {
-                    self.fatal(&format!(
-                        "failed to delete `{}`: {}",
-                        output_file.display(),
-                        e,
-                    ));
-                }
+                self.delete_file(output_file);
             } else {
                 match File::create(&output_file).and_then(|mut f| f.write_all(actual.as_bytes())) {
                     Ok(()) => {}
@@ -3054,6 +3061,42 @@
         }
     }
 
+    fn prune_duplicate_output(&self, mode: CompareMode, kind: &str, canon_content: &str) {
+        let examined_path = expected_output_path(
+            &self.testpaths,
+            self.revision,
+            &Some(mode),
+            kind,
+        );
+
+        let examined_content = self
+            .load_expected_output_from_path(&examined_path)
+            .unwrap_or_else(|_| String::new());
+
+        if examined_path.exists() && canon_content == &examined_content {
+            self.delete_file(&examined_path);
+        }
+    }
+
+    fn prune_duplicate_outputs(&self, modes: &[CompareMode]) {
+        if self.config.bless {
+            for kind in UI_EXTENSIONS {
+                let canon_comparison_path = expected_output_path(
+                    &self.testpaths,
+                    self.revision,
+                    &None,
+                    kind,
+                );
+
+                if let Ok(canon) = self.load_expected_output_from_path(&canon_comparison_path) {
+                    for mode in modes {
+                        self.prune_duplicate_output(mode.clone(), kind, &canon);
+                    }
+                }
+            }
+        }
+    }
+
     fn create_stamp(&self) {
         let mut f = File::create(::stamp(&self.config, self.testpaths, self.revision)).unwrap();
         f.write_all(compute_stamp_hash(&self.config).as_bytes())
diff --git a/src/tools/miri b/src/tools/miri
index 066a284..e173447 160000
--- a/src/tools/miri
+++ b/src/tools/miri
@@ -1 +1 @@
-Subproject commit 066a284557ff6e6a2aa19084f599f167a724af7b
+Subproject commit e1734470e780e05a3366a2f74cfa25ea88a518a5
diff --git a/src/tools/rls b/src/tools/rls
index 453f5e4..7d0bc55 160000
--- a/src/tools/rls
+++ b/src/tools/rls
@@ -1 +1 @@
-Subproject commit 453f5e4dec279167aed825b7ad043d06aa17c667
+Subproject commit 7d0bc550b0899a13a56c81eb2d5064abd0bcf385
diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js
index bc45039..3c1fcea 100644
--- a/src/tools/rustdoc-js/tester.js
+++ b/src/tools/rustdoc-js/tester.js
@@ -164,6 +164,7 @@
     m._compile(content, "tmp.js");
     m.exports.ignore_order = content.indexOf("\n// ignore-order\n") !== -1;
     m.exports.exact_check = content.indexOf("\n// exact-check\n") !== -1;
+    m.exports.should_fail = content.indexOf("\n// should-fail\n") !== -1;
     return m.exports;
 }
 
@@ -231,7 +232,9 @@
     finalJS = "";
 
     var arraysToLoad = ["itemTypes"];
-    var variablesToLoad = ["MAX_LEV_DISTANCE", "MAX_RESULTS", "TY_PRIMITIVE", "levenshtein_row2"];
+    var variablesToLoad = ["MAX_LEV_DISTANCE", "MAX_RESULTS",
+                           "TY_PRIMITIVE", "TY_KEYWORD",
+                           "levenshtein_row2"];
     // execQuery first parameter is built in getQuery (which takes in the search input).
     // execQuery last parameter is built in buildIndex.
     // buildIndex requires the hashmap from search-index.
@@ -257,6 +260,7 @@
         const query = loadedFile.QUERY;
         const ignore_order = loadedFile.ignore_order;
         const exact_check = loadedFile.exact_check;
+        const should_fail = loadedFile.should_fail;
         var results = loaded.execSearch(loaded.getQuery(query), index);
         process.stdout.write('Checking "' + file + '" ... ');
         var error_text = [];
@@ -287,7 +291,11 @@
                 }
             }
         }
-        if (error_text.length !== 0) {
+        if (error_text.length === 0 && should_fail === true) {
+            errors += 1;
+            console.error("FAILED");
+            console.error("==> Test was supposed to fail but all items were found...");
+        } else if (error_text.length !== 0 && should_fail === false) {
             errors += 1;
             console.error("FAILED");
             console.error(error_text.join("\n"));
diff --git a/src/tools/rustfmt b/src/tools/rustfmt
index 173ae0d..08da30d 160000
--- a/src/tools/rustfmt
+++ b/src/tools/rustfmt
@@ -1 +1 @@
-Subproject commit 173ae0d7b92227c7fec4bce67c944dce953256dc
+Subproject commit 08da30d72c9abfff4d41f6f081e31fd2929b820d