diff --git a/.gitmodules b/.gitmodules
index bf9bdd9a5b4b0..5cc4cab62d173 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -62,3 +62,6 @@
 	url = https://github.com/rust-lang-nursery/clang.git
 	branch = rust-release-80-v1
 
+[submodule "src/doc/rustc-guide"]
+	path = src/doc/rustc-guide
+	url = https://github.com/rust-lang/rustc-guide.git
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e04b1bdfefdd8..137fe61320796 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -640,7 +640,7 @@ are:
 * **Google!** ([search only in Rust Documentation][gsearchdocs] to find types, traits, etc. quickly)
 * Don't be afraid to ask! The Rust community is friendly and helpful.
 
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/about-this-guide.html
+[rustc guide]: https://rust-lang.github.io/rustc-guide/about-this-guide.html
 [gdfrustc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/
 [gsearchdocs]: https://www.google.com/search?q=site:doc.rust-lang.org+your+query+here
 [rif]: http://internals.rust-lang.org
@@ -648,5 +648,5 @@ are:
 [rustforge]: https://forge.rust-lang.org/
 [tlgba]: http://tomlee.co/2014/04/a-more-detailed-tour-of-the-rust-compiler/
 [ro]: http://www.rustaceans.org/
-[rctd]: https://rust-lang-nursery.github.io/rustc-guide/tests/intro.html
+[rctd]: https://rust-lang.github.io/rustc-guide/tests/intro.html
 [cheatsheet]: https://buildbot2.rust-lang.org/homu/
diff --git a/README.md b/README.md
index 0e5b7170bc6b4..37442661bcbc1 100644
--- a/README.md
+++ b/README.md
@@ -233,7 +233,7 @@ Also, you may find the [rustdocs for the compiler itself][rustdocs] useful.
 [IRC]: https://en.wikipedia.org/wiki/Internet_Relay_Chat
 [#rust]: irc://irc.mozilla.org/rust
 [#rust-beginners]: irc://irc.mozilla.org/rust-beginners
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/about-this-guide.html
+[rustc guide]: https://rust-lang.github.io/rustc-guide/about-this-guide.html
 [rustdocs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/
 
 ## License
diff --git a/config.toml.example b/config.toml.example
index 8b11014edae79..fefbb227f00b9 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -112,11 +112,11 @@
 # for each target triple.
 #target = ["x86_64-unknown-linux-gnu"] # defaults to just the build triple
 
-# Instead of downloading the src/stage0.txt version of Cargo specified, use
+# Instead of downloading the stage0.txt version of Cargo specified, use
 # this Cargo binary instead to build all Rust code
 #cargo = "/path/to/bin/cargo"
 
-# Instead of downloading the src/stage0.txt version of the compiler
+# Instead of downloading the stage0.txt version of the compiler
 # specified, use this rustc binary instead as the stage0 snapshot compiler.
 #rustc = "/path/to/bin/rustc"
 
diff --git a/src/README.md b/src/README.md
index a4f89960a0bfd..65228915866ea 100644
--- a/src/README.md
+++ b/src/README.md
@@ -12,4 +12,4 @@ There is also useful content in the following READMEs, which are gradually being
 - https://github.com/rust-lang/rust/tree/master/src/librustc/infer/higher_ranked
 - https://github.com/rust-lang/rust/tree/master/src/librustc/infer/lexical_region_resolve
 
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/about-this-guide.html
+[rustc guide]: https://rust-lang.github.io/rustc-guide/about-this-guide.html
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index d143dffb24be5..b36c1bd7bb13b 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -154,7 +154,7 @@ def run(args, verbose=False, exception=False, **kwargs):
 
 def stage0_data(rust_root):
     """Build a dictionary from stage0.txt"""
-    nightlies = os.path.join(rust_root, "src/stage0.txt")
+    nightlies = os.path.join(rust_root, "stage0.txt")
     with open(nightlies, 'r') as nightlies:
         lines = [line.rstrip() for line in nightlies
                  if not line.startswith("#")]
diff --git a/src/bootstrap/bootstrap_test.py b/src/bootstrap/bootstrap_test.py
index 4db7e2ec016f0..43cbe9967e312 100644
--- a/src/bootstrap/bootstrap_test.py
+++ b/src/bootstrap/bootstrap_test.py
@@ -28,8 +28,7 @@ class Stage0DataTestCase(unittest.TestCase):
     def setUp(self):
         self.rust_root = tempfile.mkdtemp()
         os.mkdir(os.path.join(self.rust_root, "src"))
-        with open(os.path.join(self.rust_root, "src",
-                               "stage0.txt"), "w") as stage0:
+        with open(os.path.join(self.rust_root, "stage0.txt"), "w") as stage0:
             stage0.write("#ignore\n\ndate: 2017-06-15\nrustc: beta\ncargo: beta")
 
     def tearDown(self):
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 76697e482d3a8..5c162a2c64e91 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -41,7 +41,7 @@
 //! When you execute `x.py build`, the steps which are executed are:
 //!
 //! * First, the python script is run. This will automatically download the
-//!   stage0 rustc and cargo according to `src/stage0.txt`, or use the cached
+//!   stage0 rustc and cargo according to `stage0.txt`, or use the cached
 //!   versions if they're available. These are then used to compile rustbuild
 //!   itself (using Cargo). Finally, control is then transferred to rustbuild.
 //!
@@ -777,10 +777,10 @@ impl Build {
     fn cflags(&self, target: Interned<String>, which: GitRepo) -> Vec<String> {
         // Filter out -O and /O (the optimization flags) that we picked up from
         // cc-rs because the build scripts will determine that for themselves.
-        let mut base: Vec<String> = self.cc[&target].args().iter()
+        let mut base = self.cc[&target].args().iter()
                            .map(|s| s.to_string_lossy().into_owned())
                            .filter(|s| !s.starts_with("-O") && !s.starts_with("/O"))
-                           .collect::<Vec<_>>();
+                           .collect::<Vec<String>>();
 
         // If we're compiling on macOS then we add a few unconditional flags
         // indicating that we want libc++ (more filled out than libstdc++) and
diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs
index 15d3bccba09cc..c62ce5a5b93a2 100644
--- a/src/bootstrap/sanity.rs
+++ b/src/bootstrap/sanity.rs
@@ -236,7 +236,7 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
 
     if build.config.channel == "stable" {
         let mut stage0 = String::new();
-        t!(t!(File::open(build.src.join("src/stage0.txt")))
+        t!(t!(File::open(build.src.join("stage0.txt")))
             .read_to_string(&mut stage0));
         if stage0.contains("\ndev:") {
             panic!("bootstrapping from a dev compiler in a stable release, but \
diff --git a/src/doc/index.md b/src/doc/index.md
index 33ee76739c5b2..b79a349a453b6 100644
--- a/src/doc/index.md
+++ b/src/doc/index.md
@@ -21,6 +21,9 @@ nav {
 #search-but:hover, #search-input:focus {
     border-color: #55a9ff;
 }
+h2 {
+    font-size: 18px;
+}
 </style>
 
 Welcome to an overview of the documentation provided by the Rust project.
diff --git a/src/doc/rustc-guide b/src/doc/rustc-guide
new file mode 160000
index 0000000000000..3a804956e3c28
--- /dev/null
+++ b/src/doc/rustc-guide
@@ -0,0 +1 @@
+Subproject commit 3a804956e3c28d7e44e38804207a00013594e1d3
diff --git a/src/doc/rustc/src/contributing.md b/src/doc/rustc/src/contributing.md
index fcb8e6b27dbf0..3a1cafe8a6153 100644
--- a/src/doc/rustc/src/contributing.md
+++ b/src/doc/rustc/src/contributing.md
@@ -1,6 +1,6 @@
 # Contributing to rustc
 
 We'd love to have your help improving `rustc`! To that end, we've written [a
-whole book](https://rust-lang-nursery.github.io/rustc-guide/) on its
+whole book](https://rust-lang.github.io/rustc-guide/) on its
 internals, how it works, and how to get started working on it. To learn
-more, you'll want to check that out.
\ No newline at end of file
+more, you'll want to check that out.
diff --git a/src/doc/unstable-book/src/language-features/macro-at-most-once-rep.md b/src/doc/unstable-book/src/language-features/macro-at-most-once-rep.md
deleted file mode 100644
index 251fc7209122c..0000000000000
--- a/src/doc/unstable-book/src/language-features/macro-at-most-once-rep.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# `macro_at_most_once_rep`
-
-NOTE: This feature is only available in the 2018 Edition.
-
-The tracking issue for this feature is: #48075
-
-With this feature gate enabled, one can use `?` as a Kleene operator meaning "0
-or 1 repetitions" in a macro definition. Previously only `+` and `*` were allowed.
-
-For example:
-
-```rust,ignore
-#![feature(macro_at_most_once_rep)]
-
-macro_rules! foo {
-    (something $(,)?) // `?` indicates `,` is "optional"...
-        => {}
-}
-```
-
-------------------------
-
diff --git a/src/doc/unstable-book/src/language-features/plugin.md b/src/doc/unstable-book/src/language-features/plugin.md
index 74bdd4dc3b599..03ea392c86307 100644
--- a/src/doc/unstable-book/src/language-features/plugin.md
+++ b/src/doc/unstable-book/src/language-features/plugin.md
@@ -181,7 +181,6 @@ that warns about any item named `lintme`.
 ```rust,ignore
 #![feature(plugin_registrar)]
 #![feature(box_syntax, rustc_private)]
-#![feature(macro_at_most_once_rep)]
 
 extern crate syntax;
 
diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs
index 8d009101ce7da..0b25d911a299c 100644
--- a/src/liballoc/string.rs
+++ b/src/liballoc/string.rs
@@ -618,6 +618,8 @@ impl String {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn from_utf16(v: &[u16]) -> Result<String, FromUtf16Error> {
+        // This isn't done via collect::<Result<_, _>>() for performance reasons.
+        // FIXME: the function can be simplified again when #48994 is closed.
         let mut ret = String::with_capacity(v.len());
         for c in decode_utf16(v.iter().cloned()) {
             if let Ok(c) = c {
diff --git a/src/libcore/array.rs b/src/libcore/array.rs
index 3d24f8902bd83..26e7a79d35df6 100644
--- a/src/libcore/array.rs
+++ b/src/libcore/array.rs
@@ -148,6 +148,15 @@ macro_rules! array_impls {
                 }
             }
 
+            #[unstable(feature = "try_from", issue = "33417")]
+            impl<'a, T> TryFrom<&'a [T]> for [T; $N] where T: Copy {
+                type Error = TryFromSliceError;
+
+                fn try_from(slice: &[T]) -> Result<[T; $N], TryFromSliceError> {
+                    <&Self>::try_from(slice).map(|r| *r)
+                }
+            }
+
             #[unstable(feature = "try_from", issue = "33417")]
             impl<'a, T> TryFrom<&'a [T]> for &'a [T; $N] {
                 type Error = TryFromSliceError;
diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs
index fd4189ef50df5..3063cb1a7df44 100644
--- a/src/libcore/iter/iterator.rs
+++ b/src/libcore/iter/iterator.rs
@@ -519,7 +519,7 @@ pub trait Iterator {
     /// element.
     ///
     /// `map()` transforms one iterator into another, by means of its argument:
-    /// something that implements `FnMut`. It produces a new iterator which
+    /// something that implements [`FnMut`]. It produces a new iterator which
     /// calls this closure on each element of the original iterator.
     ///
     /// If you are good at thinking in types, you can think of `map()` like this:
@@ -533,6 +533,7 @@ pub trait Iterator {
     /// more idiomatic to use [`for`] than `map()`.
     ///
     /// [`for`]: ../../book/ch03-05-control-flow.html#looping-through-a-collection-with-for
+    /// [`FnMut`]: ../../std/ops/trait.FnMut.html
     ///
     /// # Examples
     ///
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index a02b5bc87c5e9..726e891df0ccf 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -93,7 +93,6 @@
 #![feature(never_type)]
 #![feature(nll)]
 #![feature(exhaustive_patterns)]
-#![feature(macro_at_most_once_rep)]
 #![feature(no_core)]
 #![feature(on_unimplemented)]
 #![feature(optin_builtin_traits)]
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 57b5903c9d39f..46c098c8236a0 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -1989,6 +1989,19 @@ big endian.
 ```
 let value = ", stringify!($SelfT), "::from_be_bytes(", $be_bytes, ");
 assert_eq!(value, ", $swap_op, ");
+```
+
+When starting from a slice rather than an array, fallible conversion APIs can be used:
+
+```
+#![feature(try_from)]
+use std::convert::TryInto;
+
+fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
+    let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
+    *input = rest;
+    ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())
+}
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
             #[rustc_const_unstable(feature = "const_int_conversion")]
@@ -2008,6 +2021,19 @@ little endian.
 ```
 let value = ", stringify!($SelfT), "::from_le_bytes(", $le_bytes, ");
 assert_eq!(value, ", $swap_op, ");
+```
+
+When starting from a slice rather than an array, fallible conversion APIs can be used:
+
+```
+#![feature(try_from)]
+use std::convert::TryInto;
+
+fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
+    let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
+    *input = rest;
+    ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())
+}
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
             #[rustc_const_unstable(feature = "const_int_conversion")]
@@ -2037,6 +2063,19 @@ let value = ", stringify!($SelfT), "::from_ne_bytes(if cfg!(target_endian = \"bi
         ", $le_bytes, "
     });
 assert_eq!(value, ", $swap_op, ");
+```
+
+When starting from a slice rather than an array, fallible conversion APIs can be used:
+
+```
+#![feature(try_from)]
+use std::convert::TryInto;
+
+fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
+    let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
+    *input = rest;
+    ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())
+}
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
             #[rustc_const_unstable(feature = "const_int_conversion")]
@@ -3719,6 +3758,19 @@ big endian.
 ```
 let value = ", stringify!($SelfT), "::from_be_bytes(", $be_bytes, ");
 assert_eq!(value, ", $swap_op, ");
+```
+
+When starting from a slice rather than an array, fallible conversion APIs can be used:
+
+```
+#![feature(try_from)]
+use std::convert::TryInto;
+
+fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
+    let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
+    *input = rest;
+    ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())
+}
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
             #[rustc_const_unstable(feature = "const_int_conversion")]
@@ -3738,6 +3790,19 @@ little endian.
 ```
 let value = ", stringify!($SelfT), "::from_le_bytes(", $le_bytes, ");
 assert_eq!(value, ", $swap_op, ");
+```
+
+When starting from a slice rather than an array, fallible conversion APIs can be used:
+
+```
+#![feature(try_from)]
+use std::convert::TryInto;
+
+fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
+    let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
+    *input = rest;
+    ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())
+}
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
             #[rustc_const_unstable(feature = "const_int_conversion")]
@@ -3767,6 +3832,19 @@ let value = ", stringify!($SelfT), "::from_ne_bytes(if cfg!(target_endian = \"bi
         ", $le_bytes, "
     });
 assert_eq!(value, ", $swap_op, ");
+```
+
+When starting from a slice rather than an array, fallible conversion APIs can be used:
+
+```
+#![feature(try_from)]
+use std::convert::TryInto;
+
+fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {
+    let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());
+    *input = rest;
+    ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())
+}
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
             #[rustc_const_unstable(feature = "const_int_conversion")]
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 947b67e4e9af3..d3a74ed2a6856 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -189,12 +189,22 @@ pub use intrinsics::write_bytes;
 /// i.e., you do not usually have to worry about such issues unless you call `drop_in_place`
 /// manually.
 #[stable(feature = "drop_in_place", since = "1.8.0")]
+#[inline(always)]
+pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
+    real_drop_in_place(&mut *to_drop)
+}
+
+// The real `drop_in_place` -- the one that gets called implicitly when variables go
+// out of scope -- should have a safe reference and not a raw pointer as argument
+// type.  When we drop a local variable, we access it with a pointer that behaves
+// like a safe reference; transmuting that to a raw pointer does not mean we can
+// actually access it with raw pointers.
 #[lang = "drop_in_place"]
 #[allow(unconditional_recursion)]
-pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
+unsafe fn real_drop_in_place<T: ?Sized>(to_drop: &mut T) {
     // Code here does not matter - this is replaced by the
     // real drop glue by the compiler.
-    drop_in_place(to_drop);
+    real_drop_in_place(to_drop)
 }
 
 /// Creates a null raw pointer.
diff --git a/src/libcore/str/lossy.rs b/src/libcore/str/lossy.rs
index 186d6adbc91cf..52abd8f99529b 100644
--- a/src/libcore/str/lossy.rs
+++ b/src/libcore/str/lossy.rs
@@ -62,18 +62,15 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> {
         }
 
         const TAG_CONT_U8: u8 = 128;
-        fn unsafe_get(xs: &[u8], i: usize) -> u8 {
-            unsafe { *xs.get_unchecked(i) }
-        }
         fn safe_get(xs: &[u8], i: usize) -> u8 {
-            if i >= xs.len() { 0 } else { unsafe_get(xs, i) }
+            *xs.get(i).unwrap_or(&0)
         }
 
         let mut i = 0;
         while i < self.source.len() {
             let i_ = i;
 
-            let byte = unsafe_get(self.source, i);
+            let byte = unsafe { *self.source.get_unchecked(i) };
             i += 1;
 
             if byte < 128 {
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index 56d3b429fdb44..27eeb045bb196 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -173,11 +173,11 @@ unsafe impl<T> Sync for AtomicPtr<T> {}
 
 /// Atomic memory orderings
 ///
-/// Memory orderings limit the ways that both the compiler and CPU may reorder
-/// instructions around atomic operations. At its most restrictive,
-/// "sequentially consistent" atomics allow neither reads nor writes
-/// to be moved either before or after the atomic operation; on the other end
-/// "relaxed" atomics allow all reorderings.
+/// Memory orderings specify the way atomic operations synchronize memory.
+/// In its weakest [`Relaxed`][Ordering::Relaxed], only the memory directly touched by the
+/// operation is synchronized. On the other hand, a store-load pair of [`SeqCst`][Ordering::SeqCst]
+/// operations synchronize other memory while additionally preserving a total order of such
+/// operations across all threads.
 ///
 /// Rust's memory orderings are [the same as
 /// LLVM's](https://llvm.org/docs/LangRef.html#memory-model-for-concurrent-operations).
@@ -185,6 +185,8 @@ unsafe impl<T> Sync for AtomicPtr<T> {}
 /// For more information see the [nomicon].
 ///
 /// [nomicon]: ../../../nomicon/atomics.html
+/// [Ordering::Relaxed]: #variant.Relaxed
+/// [Ordering::SeqCst]: #variant.SeqCst
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Copy, Clone, Debug)]
 #[non_exhaustive]
@@ -234,8 +236,8 @@ pub enum Ordering {
     /// For loads it uses [`Acquire`] ordering. For stores it uses the [`Release`] ordering.
     ///
     /// Notice that in the case of `compare_and_swap`, it is possible that the operation ends up
-    /// not performing any store and hence it has just `Acquire` ordering. However,
-    /// `AcqRel` will never perform [`Relaxed`] accesses.
+    /// not performing any store and hence it has just [`Acquire`] ordering. However,
+    /// [`AcqRel`][`AcquireRelease`] will never perform [`Relaxed`] accesses.
     ///
     /// This ordering is only applicable for operations that combine both loads and stores.
     ///
diff --git a/src/librustc/README.md b/src/librustc/README.md
index 9909ff91a18aa..c0e5c542bdc8b 100644
--- a/src/librustc/README.md
+++ b/src/librustc/README.md
@@ -1,3 +1,3 @@
 For more information about how rustc works, see the [rustc guide].
 
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/
+[rustc guide]: https://rust-lang.github.io/rustc-guide/
diff --git a/src/librustc/dep_graph/README.md b/src/librustc/dep_graph/README.md
index f1f383d7ad126..91a06e452e5fd 100644
--- a/src/librustc/dep_graph/README.md
+++ b/src/librustc/dep_graph/README.md
@@ -1,4 +1,4 @@
 To learn more about how dependency tracking works in rustc, see the [rustc
 guide].
 
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/query.html
+[rustc guide]: https://rust-lang.github.io/rustc-guide/query.html
diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs
index 63b749c548e24..4c94c993ab405 100644
--- a/src/librustc/dep_graph/graph.rs
+++ b/src/librustc/dep_graph/graph.rs
@@ -195,7 +195,7 @@ impl DepGraph {
     /// - If you need 3+ arguments, use a tuple for the
     ///   `arg` parameter.
     ///
-    /// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/incremental-compilation.html
+    /// [rustc guide]: https://rust-lang.github.io/rustc-guide/incremental-compilation.html
     pub fn with_task<'gcx, C, A, R>(&self,
                                    key: DepNode,
                                    cx: C,
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index e28193be34a44..1674320165e65 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -689,7 +689,7 @@ pub struct WhereEqPredicate {
 ///
 /// For more details, see the [rustc guide].
 ///
-/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/hir.html
+/// [rustc guide]: https://rust-lang.github.io/rustc-guide/hir.html
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Crate {
     pub module: Mod,
diff --git a/src/librustc/infer/canonical/canonicalizer.rs b/src/librustc/infer/canonical/canonicalizer.rs
index 406a36e61fbd1..54bfe90099b73 100644
--- a/src/librustc/infer/canonical/canonicalizer.rs
+++ b/src/librustc/infer/canonical/canonicalizer.rs
@@ -13,7 +13,7 @@
 //! For an overview of what canonicalization is and how it fits into
 //! rustc, check out the [chapter in the rustc guide][c].
 //!
-//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html
+//! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html
 
 use infer::canonical::{
     Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, Canonicalized,
@@ -44,7 +44,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
     /// To get a good understanding of what is happening here, check
     /// out the [chapter in the rustc guide][c].
     ///
-    /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query
+    /// [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query
     pub fn canonicalize_query<V>(
         &self,
         value: &V,
@@ -92,7 +92,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
     /// To get a good understanding of what is happening here, check
     /// out the [chapter in the rustc guide][c].
     ///
-    /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query-result
+    /// [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query-result
     pub fn canonicalize_response<V>(&self, value: &V) -> Canonicalized<'gcx, V>
     where
         V: TypeFoldable<'tcx> + Lift<'gcx>,
diff --git a/src/librustc/infer/canonical/mod.rs b/src/librustc/infer/canonical/mod.rs
index 230f8958b3385..6b0fa79b201fc 100644
--- a/src/librustc/infer/canonical/mod.rs
+++ b/src/librustc/infer/canonical/mod.rs
@@ -29,7 +29,7 @@
 //! For a more detailed look at what is happening here, check
 //! out the [chapter in the rustc guide][c].
 //!
-//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html
+//! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html
 
 use infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin};
 use rustc_data_structures::indexed_vec::IndexVec;
diff --git a/src/librustc/infer/canonical/query_response.rs b/src/librustc/infer/canonical/query_response.rs
index d32594ebdf366..8d2b1d74c554b 100644
--- a/src/librustc/infer/canonical/query_response.rs
+++ b/src/librustc/infer/canonical/query_response.rs
@@ -15,7 +15,7 @@
 //! For an overview of what canonicaliation is and how it fits into
 //! rustc, check out the [chapter in the rustc guide][c].
 //!
-//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html
+//! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html
 
 use infer::canonical::substitute::substitute_value;
 use infer::canonical::{
@@ -184,7 +184,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
     /// To get a good understanding of what is happening here, check
     /// out the [chapter in the rustc guide][c].
     ///
-    /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#processing-the-canonicalized-query-result
+    /// [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html#processing-the-canonicalized-query-result
     pub fn instantiate_query_response_and_region_obligations<R>(
         &self,
         cause: &ObligationCause<'tcx>,
diff --git a/src/librustc/infer/canonical/substitute.rs b/src/librustc/infer/canonical/substitute.rs
index e2110e148de52..ab575882f8a17 100644
--- a/src/librustc/infer/canonical/substitute.rs
+++ b/src/librustc/infer/canonical/substitute.rs
@@ -14,7 +14,7 @@
 //! For an overview of what canonicalization is and how it fits into
 //! rustc, check out the [chapter in the rustc guide][c].
 //!
-//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html
+//! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html
 
 use infer::canonical::{Canonical, CanonicalVarValues};
 use ty::fold::TypeFoldable;
diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs
index 16140e748aa1e..cf91b85807632 100644
--- a/src/librustc/infer/higher_ranked/mod.rs
+++ b/src/librustc/infer/higher_ranked/mod.rs
@@ -329,7 +329,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     /// For more information about how placeholders and HRTBs work, see
     /// the [rustc guide].
     ///
-    /// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/hrtb.html
+    /// [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/hrtb.html
     pub fn replace_bound_vars_with_placeholders<T>(
         &self,
         binder: &ty::Binder<T>
diff --git a/src/librustc/infer/lexical_region_resolve/README.md b/src/librustc/infer/lexical_region_resolve/README.md
index 6e1c4191173bc..4483e522f3a1f 100644
--- a/src/librustc/infer/lexical_region_resolve/README.md
+++ b/src/librustc/infer/lexical_region_resolve/README.md
@@ -3,7 +3,7 @@
 > WARNING: This README is obsolete and will be removed soon! For
 > more info on how the current borrowck works, see the [rustc guide].
 
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/borrowck.html
+[rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html
 
 ## Terminology
 
diff --git a/src/librustc/infer/region_constraints/README.md b/src/librustc/infer/region_constraints/README.md
index 61603e6dee686..775bbf955b830 100644
--- a/src/librustc/infer/region_constraints/README.md
+++ b/src/librustc/infer/region_constraints/README.md
@@ -3,7 +3,7 @@
 > WARNING: This README is obsolete and will be removed soon! For
 > more info on how the current borrowck works, see the [rustc guide].
 
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/borrowck.html
+[rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html
 
 ## Terminology
 
@@ -18,7 +18,7 @@ constraints over the course of a function.  Finally, at the end of
 processing a function, we process and solve the constraints all at
 once.
 
-[ti]: https://rust-lang-nursery.github.io/rustc-guide/type-inference.html
+[ti]: https://rust-lang.github.io/rustc-guide/type-inference.html
 
 The constraints are always of one of three possible forms:
 
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 0aa964a44fd2c..ddb0c5bf22ab6 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -30,7 +30,7 @@
 //!
 //! For more information about how rustc works, see the [rustc guide].
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/
+//! [rustc guide]: https://rust-lang.github.io/rustc-guide/
 //!
 //! # Note
 //!
@@ -67,7 +67,6 @@
 #![feature(integer_atomics)]
 #![feature(test)]
 #![feature(in_band_lifetimes)]
-#![feature(macro_at_most_once_rep)]
 #![feature(crate_visibility_modifier)]
 #![feature(transpose_result)]
 
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 0009a517dd1db..ab0094df0e219 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -117,8 +117,9 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> {
                 self.reachable_symbols.insert(node_id);
             }
             Some(def) => {
-                let def_id = def.def_id();
-                if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
+                if let Some((node_id, def_id)) = def.opt_def_id().and_then(|def_id| {
+                    self.tcx.hir.as_local_node_id(def_id).map(|node_id| (node_id, def_id))
+                }) {
                     if self.def_id_represents_local_inlined_item(def_id) {
                         self.worklist.push(node_id);
                     } else {
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index d00fbdeca21aa..35d1a4dd2cb7c 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -14,7 +14,7 @@
 //! For more information about how MIR-based region-checking works,
 //! see the [rustc guide].
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/borrowck.html
+//! [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html
 
 use ich::{StableHashingContext, NodeIdHashingMode};
 use util::nodemap::{FxHashMap, FxHashSet};
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 6ff450508d136..07054ee99af76 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -1573,7 +1573,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             .collect();
 
         // ensure that we issue lints in a repeatable order
-        def_ids.sort_by_key(|&def_id| self.tcx.def_path_hash(def_id));
+        def_ids.sort_by_cached_key(|&def_id| self.tcx.def_path_hash(def_id));
 
         for def_id in def_ids {
             debug!(
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index af1255c438a95..368f83eb61127 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -10,7 +10,7 @@
 
 //! MIR datatypes and passes. See the [rustc guide] for more info.
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/index.html
+//! [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/index.html
 
 use hir::def::CtorKind;
 use hir::def_id::DefId;
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 3fd22793a08a0..c5799d9130256 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -14,7 +14,7 @@
 use std::str::FromStr;
 
 use session::{early_error, early_warn, Session};
-use session::search_paths::SearchPaths;
+use session::search_paths::SearchPath;
 
 use rustc_target::spec::{LinkerFlavor, PanicStrategy, RelroLevel};
 use rustc_target::spec::{Target, TargetTriple};
@@ -374,7 +374,7 @@ top_level_options!(
         lint_cap: Option<lint::Level> [TRACKED],
         describe_lints: bool [UNTRACKED],
         output_types: OutputTypes [TRACKED],
-        search_paths: SearchPaths [UNTRACKED],
+        search_paths: Vec<SearchPath> [UNTRACKED],
         libs: Vec<(String, Option<String>, Option<cstore::NativeLibraryKind>)> [TRACKED],
         maybe_sysroot: Option<PathBuf> [TRACKED],
 
@@ -593,7 +593,7 @@ impl Default for Options {
             lint_cap: None,
             describe_lints: false,
             output_types: OutputTypes(BTreeMap::new()),
-            search_paths: SearchPaths::new(),
+            search_paths: vec![],
             maybe_sysroot: None,
             target_triple: TargetTriple::from_triple(host_triple()),
             test: false,
@@ -2112,9 +2112,9 @@ pub fn build_session_options_and_crate_config(
         }
     };
 
-    let mut search_paths = SearchPaths::new();
+    let mut search_paths = vec![];
     for s in &matches.opt_strs("L") {
-        search_paths.add_path(&s[..], error_format);
+        search_paths.push(SearchPath::from_cli_opt(&s[..], error_format));
     }
 
     let libs = matches
@@ -2532,6 +2532,7 @@ mod tests {
     use session::config::{build_configuration, build_session_options_and_crate_config};
     use session::config::{LtoCli, CrossLangLto};
     use session::build_session;
+    use session::search_paths::SearchPath;
     use std::collections::{BTreeMap, BTreeSet};
     use std::iter::FromIterator;
     use std::path::PathBuf;
@@ -2787,48 +2788,48 @@ mod tests {
 
         // Reference
         v1.search_paths
-            .add_path("native=abc", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("native=abc", super::ErrorOutputType::Json(false)));
         v1.search_paths
-            .add_path("crate=def", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("crate=def", super::ErrorOutputType::Json(false)));
         v1.search_paths
-            .add_path("dependency=ghi", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("dependency=ghi", super::ErrorOutputType::Json(false)));
         v1.search_paths
-            .add_path("framework=jkl", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("framework=jkl", super::ErrorOutputType::Json(false)));
         v1.search_paths
-            .add_path("all=mno", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("all=mno", super::ErrorOutputType::Json(false)));
 
         v2.search_paths
-            .add_path("native=abc", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("native=abc", super::ErrorOutputType::Json(false)));
         v2.search_paths
-            .add_path("dependency=ghi", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("dependency=ghi", super::ErrorOutputType::Json(false)));
         v2.search_paths
-            .add_path("crate=def", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("crate=def", super::ErrorOutputType::Json(false)));
         v2.search_paths
-            .add_path("framework=jkl", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("framework=jkl", super::ErrorOutputType::Json(false)));
         v2.search_paths
-            .add_path("all=mno", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("all=mno", super::ErrorOutputType::Json(false)));
 
         v3.search_paths
-            .add_path("crate=def", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("crate=def", super::ErrorOutputType::Json(false)));
         v3.search_paths
-            .add_path("framework=jkl", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("framework=jkl", super::ErrorOutputType::Json(false)));
         v3.search_paths
-            .add_path("native=abc", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("native=abc", super::ErrorOutputType::Json(false)));
         v3.search_paths
-            .add_path("dependency=ghi", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("dependency=ghi", super::ErrorOutputType::Json(false)));
         v3.search_paths
-            .add_path("all=mno", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("all=mno", super::ErrorOutputType::Json(false)));
 
         v4.search_paths
-            .add_path("all=mno", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("all=mno", super::ErrorOutputType::Json(false)));
         v4.search_paths
-            .add_path("native=abc", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("native=abc", super::ErrorOutputType::Json(false)));
         v4.search_paths
-            .add_path("crate=def", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("crate=def", super::ErrorOutputType::Json(false)));
         v4.search_paths
-            .add_path("dependency=ghi", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("dependency=ghi", super::ErrorOutputType::Json(false)));
         v4.search_paths
-            .add_path("framework=jkl", super::ErrorOutputType::Json(false));
+            .push(SearchPath::from_cli_opt("framework=jkl", super::ErrorOutputType::Json(false)));
 
         assert!(v1.dep_tracking_hash() == v2.dep_tracking_hash());
         assert!(v1.dep_tracking_hash() == v3.dep_tracking_hash());
diff --git a/src/librustc/session/filesearch.rs b/src/librustc/session/filesearch.rs
index f410c270bcef9..402f6216250d4 100644
--- a/src/librustc/session/filesearch.rs
+++ b/src/librustc/session/filesearch.rs
@@ -12,13 +12,12 @@
 
 pub use self::FileMatch::*;
 
-use rustc_data_structures::fx::FxHashSet;
 use std::borrow::Cow;
 use std::env;
 use std::fs;
 use std::path::{Path, PathBuf};
 
-use session::search_paths::{SearchPaths, PathKind};
+use session::search_paths::{SearchPath, PathKind};
 use rustc_fs_util::fix_windows_verbatim_for_gcc;
 
 #[derive(Copy, Clone)]
@@ -30,31 +29,19 @@ pub enum FileMatch {
 // A module for searching for libraries
 
 pub struct FileSearch<'a> {
-    pub sysroot: &'a Path,
-    pub search_paths: &'a SearchPaths,
-    pub triple: &'a str,
-    pub kind: PathKind,
+    sysroot: &'a Path,
+    triple: &'a str,
+    search_paths: &'a [SearchPath],
+    tlib_path: &'a SearchPath,
+    kind: PathKind,
 }
 
 impl<'a> FileSearch<'a> {
-    pub fn for_each_lib_search_path<F>(&self, mut f: F) where
-        F: FnMut(&Path, PathKind)
-    {
-        let mut visited_dirs = FxHashSet::default();
-        visited_dirs.reserve(self.search_paths.paths.len() + 1);
-        for (path, kind) in self.search_paths.iter(self.kind) {
-            f(path, kind);
-            visited_dirs.insert(path.to_path_buf());
-        }
-
-        debug!("filesearch: searching lib path");
-        let tlib_path = make_target_lib_path(self.sysroot,
-                                             self.triple);
-        if !visited_dirs.contains(&tlib_path) {
-            f(&tlib_path, PathKind::All);
-        }
-
-        visited_dirs.insert(tlib_path);
+    pub fn search_paths(&self) -> impl Iterator<Item = &'a SearchPath> {
+        let kind = self.kind;
+        self.search_paths.iter()
+            .filter(move |sp| sp.kind.matches(kind))
+            .chain(std::iter::once(self.tlib_path))
     }
 
     pub fn get_lib_path(&self) -> PathBuf {
@@ -64,14 +51,8 @@ impl<'a> FileSearch<'a> {
     pub fn search<F>(&self, mut pick: F)
         where F: FnMut(&Path, PathKind) -> FileMatch
     {
-        self.for_each_lib_search_path(|lib_search_path, kind| {
-            debug!("searching {}", lib_search_path.display());
-            let files = match fs::read_dir(lib_search_path) {
-                Ok(files) => files,
-                Err(..) => return,
-            };
-            let files = files.filter_map(|p| p.ok().map(|s| s.path()))
-                             .collect::<Vec<_>>();
+        for search_path in self.search_paths() {
+            debug!("searching {}", search_path.dir.display());
             fn is_rlib(p: &Path) -> bool {
                 p.extension() == Some("rlib".as_ref())
             }
@@ -79,11 +60,11 @@ impl<'a> FileSearch<'a> {
             // an rlib and a dylib we only read one of the files of
             // metadata, so in the name of speed, bring all rlib files to
             // the front of the search list.
-            let files1 = files.iter().filter(|p| is_rlib(p));
-            let files2 = files.iter().filter(|p| !is_rlib(p));
+            let files1 = search_path.files.iter().filter(|p| is_rlib(p));
+            let files2 = search_path.files.iter().filter(|p| !is_rlib(p));
             for path in files1.chain(files2) {
                 debug!("testing {}", path.display());
-                let maybe_picked = pick(path, kind);
+                let maybe_picked = pick(path, search_path.kind);
                 match maybe_picked {
                     FileMatches => {
                         debug!("picked {}", path.display());
@@ -93,29 +74,30 @@ impl<'a> FileSearch<'a> {
                     }
                 }
             }
-        });
+        }
     }
 
     pub fn new(sysroot: &'a Path,
                triple: &'a str,
-               search_paths: &'a SearchPaths,
-               kind: PathKind) -> FileSearch<'a> {
+               search_paths: &'a Vec<SearchPath>,
+               tlib_path: &'a SearchPath,
+               kind: PathKind)
+               -> FileSearch<'a> {
         debug!("using sysroot = {}, triple = {}", sysroot.display(), triple);
         FileSearch {
             sysroot,
-            search_paths,
             triple,
+            search_paths,
+            tlib_path,
             kind,
         }
     }
 
-    // Returns a list of directories where target-specific dylibs might be located.
-    pub fn get_dylib_search_paths(&self) -> Vec<PathBuf> {
-        let mut paths = Vec::new();
-        self.for_each_lib_search_path(|lib_search_path, _| {
-            paths.push(lib_search_path.to_path_buf());
-        });
-        paths
+    // Returns just the directories within the search paths.
+    pub fn search_path_dirs(&self) -> Vec<PathBuf> {
+        self.search_paths()
+            .map(|sp| sp.dir.to_path_buf())
+            .collect()
     }
 
     // Returns a list of directories where target-specific tool binaries are located.
@@ -138,8 +120,7 @@ pub fn relative_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf
     p
 }
 
-fn make_target_lib_path(sysroot: &Path,
-                        target_triple: &str) -> PathBuf {
+pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
     sysroot.join(&relative_target_lib_path(sysroot, target_triple))
 }
 
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 1187c53305d1c..6b323d89ed0dd 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -19,8 +19,8 @@ use lint;
 use lint::builtin::BuiltinLintDiagnostics;
 use middle::allocator::AllocatorKind;
 use middle::dependency_format;
-use session::search_paths::PathKind;
 use session::config::{OutputType, Lto};
+use session::search_paths::{PathKind, SearchPath};
 use util::nodemap::{FxHashMap, FxHashSet};
 use util::common::{duration_to_secs_str, ErrorReported};
 use util::common::ProfileQueriesMsg;
@@ -48,7 +48,7 @@ use std::cell::{self, Cell, RefCell};
 use std::env;
 use std::fmt;
 use std::io::Write;
-use std::path::{Path, PathBuf};
+use std::path::PathBuf;
 use std::time::Duration;
 use std::sync::mpsc;
 use std::sync::atomic::{AtomicUsize, Ordering};
@@ -64,12 +64,15 @@ pub struct Session {
     pub target: config::Config,
     pub host: Target,
     pub opts: config::Options,
+    pub host_tlib_path: SearchPath,
+    /// This is `None` if the host and target are the same.
+    pub target_tlib_path: Option<SearchPath>,
     pub parse_sess: ParseSess,
     /// For a library crate, this is always none
     pub entry_fn: Once<Option<(NodeId, Span, config::EntryFnType)>>,
     pub plugin_registrar_fn: Once<Option<ast::NodeId>>,
     pub derive_registrar_fn: Once<Option<ast::NodeId>>,
-    pub default_sysroot: Option<PathBuf>,
+    pub sysroot: PathBuf,
     /// The name of the root source file of the crate, in the local file system.
     /// `None` means that there is no source file.
     pub local_crate_source_file: Option<PathBuf>,
@@ -694,27 +697,22 @@ impl Session {
         )
     }
 
-    pub fn sysroot<'a>(&'a self) -> &'a Path {
-        match self.opts.maybe_sysroot {
-            Some(ref sysroot) => sysroot,
-            None => self.default_sysroot
-                        .as_ref()
-                        .expect("missing sysroot and default_sysroot in Session"),
-        }
-    }
     pub fn target_filesearch(&self, kind: PathKind) -> filesearch::FileSearch<'_> {
         filesearch::FileSearch::new(
-            self.sysroot(),
+            &self.sysroot,
             self.opts.target_triple.triple(),
             &self.opts.search_paths,
+            // target_tlib_path==None means it's the same as host_tlib_path.
+            self.target_tlib_path.as_ref().unwrap_or(&self.host_tlib_path),
             kind,
         )
     }
     pub fn host_filesearch(&self, kind: PathKind) -> filesearch::FileSearch<'_> {
         filesearch::FileSearch::new(
-            self.sysroot(),
+            &self.sysroot,
             config::host_triple(),
             &self.opts.search_paths,
+            &self.host_tlib_path,
             kind,
         )
     }
@@ -1109,9 +1107,18 @@ pub fn build_session_(
     let target_cfg = config::build_target_config(&sopts, &span_diagnostic);
 
     let p_s = parse::ParseSess::with_span_handler(span_diagnostic, source_map);
-    let default_sysroot = match sopts.maybe_sysroot {
-        Some(_) => None,
-        None => Some(filesearch::get_or_default_sysroot()),
+    let sysroot = match &sopts.maybe_sysroot {
+        Some(sysroot) => sysroot.clone(),
+        None => filesearch::get_or_default_sysroot(),
+    };
+
+    let host_triple = config::host_triple();
+    let target_triple = sopts.target_triple.triple();
+    let host_tlib_path = SearchPath::from_sysroot_and_triple(&sysroot, host_triple);
+    let target_tlib_path = if host_triple == target_triple {
+        None
+    } else {
+        Some(SearchPath::from_sysroot_and_triple(&sysroot, target_triple))
     };
 
     let file_path_mapping = sopts.file_path_mapping();
@@ -1142,12 +1149,14 @@ pub fn build_session_(
         target: target_cfg,
         host,
         opts: sopts,
+        host_tlib_path,
+        target_tlib_path,
         parse_sess: p_s,
         // For a library crate, this is always none
         entry_fn: Once::new(),
         plugin_registrar_fn: Once::new(),
         derive_registrar_fn: Once::new(),
-        default_sysroot,
+        sysroot,
         local_crate_source_file,
         working_dir,
         lint_store: RwLock::new(lint::LintStore::new()),
diff --git a/src/librustc/session/search_paths.rs b/src/librustc/session/search_paths.rs
index 768d4f1e5fb65..5c44a07f84341 100644
--- a/src/librustc/session/search_paths.rs
+++ b/src/librustc/session/search_paths.rs
@@ -8,18 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::slice;
 use std::path::{Path, PathBuf};
 use session::{early_error, config};
+use session::filesearch::make_target_lib_path;
 
 #[derive(Clone, Debug)]
-pub struct SearchPaths {
-    crate paths: Vec<(PathKind, PathBuf)>,
-}
-
-pub struct Iter<'a> {
-    kind: PathKind,
-    iter: slice::Iter<'a, (PathKind, PathBuf)>,
+pub struct SearchPath {
+    pub kind: PathKind,
+    pub dir: PathBuf,
+    pub files: Vec<PathBuf>,
 }
 
 #[derive(Eq, PartialEq, Clone, Copy, Debug, PartialOrd, Ord, Hash)]
@@ -32,12 +29,17 @@ pub enum PathKind {
     All,
 }
 
-impl SearchPaths {
-    pub fn new() -> SearchPaths {
-        SearchPaths { paths: Vec::new() }
+impl PathKind {
+    pub fn matches(&self, kind: PathKind) -> bool {
+        match (self, kind) {
+            (PathKind::All, _) | (_, PathKind::All) => true,
+            _ => *self == kind,
+        }
     }
+}
 
-    pub fn add_path(&mut self, path: &str, output: config::ErrorOutputType) {
+impl SearchPath {
+    pub fn from_cli_opt(path: &str, output: config::ErrorOutputType) -> Self {
         let (kind, path) = if path.starts_with("native=") {
             (PathKind::Native, &path["native=".len()..])
         } else if path.starts_with("crate=") {
@@ -54,35 +56,28 @@ impl SearchPaths {
         if path.is_empty() {
             early_error(output, "empty search path given via `-L`");
         }
-        self.paths.push((kind, PathBuf::from(path)));
-    }
 
-    pub fn iter(&self, kind: PathKind) -> Iter<'_> {
-        Iter { kind: kind, iter: self.paths.iter() }
+        let dir = PathBuf::from(path);
+        Self::new(kind, dir)
     }
-}
 
-impl<'a> Iterator for Iter<'a> {
-    type Item = (&'a Path, PathKind);
+    pub fn from_sysroot_and_triple(sysroot: &Path, triple: &str) -> Self {
+        Self::new(PathKind::All, make_target_lib_path(sysroot, triple))
+    }
 
-    fn next(&mut self) -> Option<(&'a Path, PathKind)> {
-        loop {
-            match self.iter.next() {
-                Some(&(kind, ref p)) if self.kind == PathKind::All ||
-                                        kind == PathKind::All ||
-                                        kind == self.kind => {
-                    return Some((p, kind))
-                }
-                Some(..) => {}
-                None => return None,
+    fn new(kind: PathKind, dir: PathBuf) -> Self {
+        // Get the files within the directory.
+        let files = match std::fs::read_dir(&dir) {
+            Ok(files) => {
+                files.filter_map(|p| {
+                    p.ok().map(|s| s.path())
+                })
+                .collect::<Vec<_>>()
             }
-        }
-    }
+            Err(..) => vec![],
+        };
 
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        // This iterator will never return more elements than the base iterator;
-        // but it can ignore all the remaining elements.
-        let (_, upper) = self.iter.size_hint();
-        (0, upper)
+        SearchPath { kind, dir, files }
     }
 }
+
diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs
index b7a84c99308f8..4bf8ba0d6d1c8 100644
--- a/src/librustc/traits/coherence.rs
+++ b/src/librustc/traits/coherence.rs
@@ -11,8 +11,8 @@
 //! See rustc guide chapters on [trait-resolution] and [trait-specialization] for more info on how
 //! this works.
 //!
-//! [trait-resolution]: https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html
-//! [trait-specialization]: https://rust-lang-nursery.github.io/rustc-guide/traits/specialization.html
+//! [trait-resolution]: https://rust-lang.github.io/rustc-guide/traits/resolution.html
+//! [trait-specialization]: https://rust-lang.github.io/rustc-guide/traits/specialization.html
 
 use hir::def_id::{DefId, LOCAL_CRATE};
 use syntax_pos::DUMMY_SP;
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index 8c3cd5e6612b9..e582a9020464d 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -10,7 +10,7 @@
 
 //! Trait Resolution. See [rustc guide] for more info on how this works.
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html
+//! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/resolution.html
 
 pub use self::SelectionError::*;
 pub use self::FulfillmentErrorCode::*;
diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs
index c79fa3861234f..2909daf22b3ba 100644
--- a/src/librustc/traits/object_safety.rs
+++ b/src/librustc/traits/object_safety.rs
@@ -409,7 +409,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
             .collect::<Vec<_>>();
 
         // existential predicates need to be in a specific order
-        associated_types.sort_by_key(|item| self.def_path_hash(item.def_id));
+        associated_types.sort_by_cached_key(|item| self.def_path_hash(item.def_id));
 
         let projection_predicates = associated_types.into_iter().map(|item| {
             ty::ExistentialPredicate::Projection(ty::ExistentialProjection {
diff --git a/src/librustc/traits/query/type_op/mod.rs b/src/librustc/traits/query/type_op/mod.rs
index d20d43cf7578c..f8f9650ebe1ae 100644
--- a/src/librustc/traits/query/type_op/mod.rs
+++ b/src/librustc/traits/query/type_op/mod.rs
@@ -53,7 +53,7 @@ pub trait TypeOp<'gcx, 'tcx>: Sized + fmt::Debug {
 /// first canonicalize the key and then invoke the query on the tcx,
 /// which produces the resulting query region constraints.
 ///
-/// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html
+/// [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html
 pub trait QueryTypeOp<'gcx: 'tcx, 'tcx>:
     fmt::Debug + Sized + TypeFoldable<'tcx> + Lift<'gcx>
 {
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 0f59f478cb415..fb4c9f3bad715 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -10,7 +10,7 @@
 
 //! See [rustc guide] for more info on how this works.
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html#selection
+//! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/resolution.html#selection
 
 use self::EvaluationResult::*;
 use self::SelectionCandidate::*;
@@ -1173,7 +1173,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
     // candidates. See [rustc guide] for more details.
     //
     // [rustc guide]:
-    // https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html#candidate-assembly
+    // https://rust-lang.github.io/rustc-guide/traits/resolution.html#candidate-assembly
 
     fn candidate_from_obligation<'o>(
         &mut self,
@@ -2720,7 +2720,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
     // type error.  See [rustc guide] for more details.
     //
     // [rustc guide]:
-    // https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html#confirmation
+    // https://rust-lang.github.io/rustc-guide/traits/resolution.html#confirmation
 
     fn confirm_candidate(
         &mut self,
diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs
index d3dc1655b0df2..19ef3171b13fc 100644
--- a/src/librustc/traits/specialize/mod.rs
+++ b/src/librustc/traits/specialize/mod.rs
@@ -17,7 +17,7 @@
 //! See the [rustc guide] for a bit more detail on how specialization
 //! fits together with the rest of the trait machinery.
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/specialization.html
+//! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/specialization.html
 
 use super::{SelectionContext, FulfillmentContext};
 use super::util::impl_trait_ref_and_oblig;
diff --git a/src/librustc/ty/constness.rs b/src/librustc/ty/constness.rs
index 47aea7a5f0796..e32913b8905b7 100644
--- a/src/librustc/ty/constness.rs
+++ b/src/librustc/ty/constness.rs
@@ -66,7 +66,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
             }
         } else {
             // users enabling the `const_fn` feature gate can do what they want
-            !self.sess.features_untracked().const_fn
+            !self.features().const_fn
         }
     }
 }
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 5780fbe55ad1f..79a4638d6f7d9 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -876,7 +876,7 @@ pub struct FreeRegionInfo {
 /// various **compiler queries** that have been performed. See the
 /// [rustc guide] for more details.
 ///
-/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/ty.html
+/// [rustc guide]: https://rust-lang.github.io/rustc-guide/ty.html
 #[derive(Copy, Clone)]
 pub struct TyCtxt<'a, 'gcx: 'tcx, 'tcx: 'a> {
     gcx: &'a GlobalCtxt<'gcx>,
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 3056abba95626..a18e3a275467d 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -1138,7 +1138,7 @@ pub type Region<'tcx> = &'tcx RegionKind;
 ///
 /// [1]: http://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
 /// [2]: http://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
-/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/hrtb.html
+/// [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/hrtb.html
 #[derive(Clone, PartialEq, Eq, Hash, Copy, RustcEncodable, RustcDecodable, PartialOrd, Ord)]
 pub enum RegionKind {
     // Region bound in a type or fn declaration which will be
diff --git a/src/librustc/util/profiling.rs b/src/librustc/util/profiling.rs
index 6540a09d87763..bea3453b31adf 100644
--- a/src/librustc/util/profiling.rs
+++ b/src/librustc/util/profiling.rs
@@ -102,7 +102,7 @@ macro_rules! define_categories {
                         };
 
                     json.push_str(&format!(
-                        "{{ \"category\": {}, \"time_ms\": {},
+                        "{{ \"category\": \"{}\", \"time_ms\": {},\
                             \"query_count\": {}, \"query_hits\": {} }},",
                         stringify!($name),
                         self.times.$name / 1_000_000,
diff --git a/src/librustc_borrowck/borrowck/README.md b/src/librustc_borrowck/borrowck/README.md
index 8bc0b4969b8f9..a05c56e3629a3 100644
--- a/src/librustc_borrowck/borrowck/README.md
+++ b/src/librustc_borrowck/borrowck/README.md
@@ -3,7 +3,7 @@
 > WARNING: This README is more or less obsolete, and will be removed
 > soon! The new system is described in the [rustc guide].
 
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/borrowck.html
+[rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html
 
 This pass has the job of enforcing memory safety. This is a subtle
 topic. This docs aim to explain both the practice and the theory
diff --git a/src/librustc_codegen_llvm/README.md b/src/librustc_codegen_llvm/README.md
index 8d1c9a52b2428..dda2e5ac18f01 100644
--- a/src/librustc_codegen_llvm/README.md
+++ b/src/librustc_codegen_llvm/README.md
@@ -4,4 +4,4 @@ that runs towards the end of the compilation process.
 
 For more information about how codegen works, see the [rustc guide].
 
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/codegen.html
+[rustc guide]: https://rust-lang.github.io/rustc-guide/codegen.html
diff --git a/src/librustc_codegen_llvm/back/link.rs b/src/librustc_codegen_llvm/back/link.rs
index 89d84acdd8876..6242ad80a8c90 100644
--- a/src/librustc_codegen_llvm/back/link.rs
+++ b/src/librustc_codegen_llvm/back/link.rs
@@ -212,12 +212,7 @@ fn link_binary_output(sess: &Session,
 }
 
 fn archive_search_paths(sess: &Session) -> Vec<PathBuf> {
-    let mut search = Vec::new();
-    sess.target_filesearch(PathKind::Native).for_each_lib_search_path(|path, _| {
-        search.push(path.to_path_buf());
-    });
-
-    search
+    sess.target_filesearch(PathKind::Native).search_path_dirs()
 }
 
 fn archive_config<'a>(sess: &'a Session,
@@ -1024,11 +1019,10 @@ fn link_args(cmd: &mut dyn Linker,
     // where extern libraries might live, based on the
     // addl_lib_search_paths
     if sess.opts.cg.rpath {
-        let sysroot = sess.sysroot();
         let target_triple = sess.opts.target_triple.triple();
         let mut get_install_prefix_lib_path = || {
             let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX");
-            let tlib = filesearch::relative_target_lib_path(sysroot, target_triple);
+            let tlib = filesearch::relative_target_lib_path(&sess.sysroot, target_triple);
             let mut path = PathBuf::from(install_prefix);
             path.push(&tlib);
 
@@ -1068,12 +1062,13 @@ fn link_args(cmd: &mut dyn Linker,
 fn add_local_native_libraries(cmd: &mut dyn Linker,
                               sess: &Session,
                               codegen_results: &CodegenResults) {
-    sess.target_filesearch(PathKind::All).for_each_lib_search_path(|path, k| {
-        match k {
-            PathKind::Framework => { cmd.framework_path(path); }
-            _ => { cmd.include_path(&fix_windows_verbatim_for_gcc(path)); }
+    let filesearch = sess.target_filesearch(PathKind::All);
+    for search_path in filesearch.search_paths() {
+        match search_path.kind {
+            PathKind::Framework => { cmd.framework_path(&search_path.dir); }
+            _ => { cmd.include_path(&fix_windows_verbatim_for_gcc(&search_path.dir)); }
         }
-    });
+    }
 
     let relevant_libs = codegen_results.crate_info.used_libraries.iter().filter(|l| {
         relevant_lib(sess, l)
diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs
index f3cc344254fea..1130c13fbd1f8 100644
--- a/src/librustc_codegen_ssa/back/linker.rs
+++ b/src/librustc_codegen_ssa/back/linker.rs
@@ -606,8 +606,7 @@ impl<'a> Linker for MsvcLinker<'a> {
         self.cmd.arg("/DEBUG");
 
         // This will cause the Microsoft linker to embed .natvis info into the PDB file
-        let sysroot = self.sess.sysroot();
-        let natvis_dir_path = sysroot.join("lib\\rustlib\\etc");
+        let natvis_dir_path = self.sess.sysroot.join("lib\\rustlib\\etc");
         if let Ok(natvis_dir) = fs::read_dir(&natvis_dir_path) {
             // LLVM 5.0.0's lld-link frontend doesn't yet recognize, and chokes
             // on, the /NATVIS:... flags.  LLVM 6 (or earlier) should at worst ignore
diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs
index 92d0219caf06b..fefbc14e4973c 100644
--- a/src/librustc_codegen_ssa/mir/operand.rs
+++ b/src/librustc_codegen_ssa/mir/operand.rs
@@ -331,11 +331,21 @@ impl<'a, 'tcx: 'a, V: CodegenObject> OperandValue<V> {
                 bx.store_with_flags(val, dest.llval, dest.align, flags);
             }
             OperandValue::Pair(a, b) => {
-                for (i, &x) in [a, b].iter().enumerate() {
-                    let llptr = bx.struct_gep(dest.llval, i as u64);
-                    let val = base::from_immediate(bx, x);
-                    bx.store_with_flags(val, llptr, dest.align, flags);
-                }
+                let (a_scalar, b_scalar) = match dest.layout.abi {
+                    layout::Abi::ScalarPair(ref a, ref b) => (a, b),
+                    _ => bug!("store_with_flags: invalid ScalarPair layout: {:#?}", dest.layout)
+                };
+                let b_offset = a_scalar.value.size(bx).align_to(b_scalar.value.align(bx).abi);
+
+                let llptr = bx.struct_gep(dest.llval, 0);
+                let val = base::from_immediate(bx, a);
+                let align = dest.align;
+                bx.store_with_flags(val, llptr, align, flags);
+
+                let llptr = bx.struct_gep(dest.llval, 1);
+                let val = base::from_immediate(bx, b);
+                let align = dest.align.restrict_for_offset(b_offset);
+                bx.store_with_flags(val, llptr, align, flags);
             }
         }
     }
diff --git a/src/librustc_driver/README.md b/src/librustc_driver/README.md
index fef249a9e4eb8..c4d73953e9b2e 100644
--- a/src/librustc_driver/README.md
+++ b/src/librustc_driver/README.md
@@ -7,4 +7,4 @@ options).
 
 For more information about how the driver works, see the [rustc guide].
 
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/rustc-driver.html
+[rustc guide]: https://rust-lang.github.io/rustc-guide/rustc-driver.html
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 7ad012409b53a..1ac3a9ff9c870 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -977,7 +977,7 @@ where
         let mut old_path = OsString::new();
         if cfg!(windows) {
             old_path = env::var_os("PATH").unwrap_or(old_path);
-            let mut new_path = sess.host_filesearch(PathKind::All).get_dylib_search_paths();
+            let mut new_path = sess.host_filesearch(PathKind::All).search_path_dirs();
             for path in env::split_paths(&old_path) {
                 if !new_path.contains(&path) {
                     new_path.push(path);
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index ec3cb95db88f8..960cdcb1a95b1 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -1042,7 +1042,7 @@ impl RustcDefaultCalls {
                     targets.sort();
                     println!("{}", targets.join("\n"));
                 },
-                Sysroot => println!("{}", sess.sysroot().display()),
+                Sysroot => println!("{}", sess.sysroot.display()),
                 TargetSpec => println!("{}", sess.target.target.to_json().pretty()),
                 FileNames | CrateName => {
                     let input = input.unwrap_or_else(||
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index 57cbecb5c67be..71efc5654eff3 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -29,7 +29,6 @@
 #![feature(nll)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
-#![feature(macro_at_most_once_rep)]
 
 #[macro_use]
 extern crate syntax;
diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs
index 0322c888ad5c9..ee99f7465b905 100644
--- a/src/librustc_metadata/lib.rs
+++ b/src/librustc_metadata/lib.rs
@@ -14,7 +14,6 @@
 
 #![feature(box_patterns)]
 #![feature(libc)]
-#![feature(macro_at_most_once_rep)]
 #![feature(nll)]
 #![feature(proc_macro_internals)]
 #![feature(proc_macro_quote)]
diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs
index 528c96f240dba..f58cc00477789 100644
--- a/src/librustc_metadata/locator.rs
+++ b/src/librustc_metadata/locator.rs
@@ -678,7 +678,7 @@ impl<'a> Context<'a> {
             // candidates are all canonicalized, so we canonicalize the sysroot
             // as well.
             if let Some((ref prev, _)) = ret {
-                let sysroot = self.sess.sysroot();
+                let sysroot = &self.sess.sysroot;
                 let sysroot = sysroot.canonicalize()
                                      .unwrap_or_else(|_| sysroot.to_path_buf());
                 if prev.starts_with(&sysroot) {
diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs
index 8f50a1e9a21b9..2db9fb9cb99f4 100644
--- a/src/librustc_mir/build/expr/as_temp.rs
+++ b/src/librustc_mir/build/expr/as_temp.rs
@@ -85,9 +85,15 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
 
         unpack!(block = this.into(&Place::Local(temp), block, expr));
 
-        // In constants, temp_lifetime is None. We should not need to drop
-        // anything because no values with a destructor can be created in
-        // a constant at this time, even if the type may need dropping.
+        // In constants, temp_lifetime is None for temporaries that live for the
+        // 'static lifetime. Thus we do not drop these temporaries and simply leak them.
+        // This is equivalent to what `let x = &foo();` does in functions. The temporary
+        // is lifted to their surrounding scope. In a function that means the temporary lives
+        // until just before the function returns. In constants that means it outlives the
+        // constant's initialization value computation. Anything outliving a constant
+        // must have the `'static` lifetime and live forever.
+        // Anything with a shorter lifetime (e.g the `&foo()` in `bar(&foo())` or anything
+        // within a block will keep the regular drops just like runtime code.
         if let Some(temp_lifetime) = temp_lifetime {
             this.schedule_drop_storage_and_value(
                 expr_span,
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index d95a74be77696..bc12c262716e6 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -915,6 +915,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
             let place = Place::Local(local);
             let &ArgInfo(ty, opt_ty_info, pattern, ref self_binding) = arg_info;
 
+            // Make sure we drop (parts of) the argument even when not matched on.
+            self.schedule_drop(
+                pattern.as_ref().map_or(ast_body.span, |pat| pat.span),
+                argument_scope, &place, ty,
+                DropKind::Value { cached_block: CachedBlock::default() },
+            );
+
             if let Some(pattern) = pattern {
                 let pattern = self.hir.pattern_from_hir(pattern);
                 let span = pattern.span;
@@ -946,13 +953,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                     }
                 }
             }
-
-            // Make sure we drop (parts of) the argument even when not matched on.
-            self.schedule_drop(
-                pattern.as_ref().map_or(ast_body.span, |pat| pat.span),
-                argument_scope, &place, ty,
-                DropKind::Value { cached_block: CachedBlock::default() },
-            );
         }
 
         // Enter the argument pattern bindings source scope, if it exists.
diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs
index bafabe4e9972c..a6bd36e582fcd 100644
--- a/src/librustc_mir/hair/pattern/check_match.rs
+++ b/src/librustc_mir/hair/pattern/check_match.rs
@@ -234,7 +234,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
                 if !scrutinee_is_uninhabited {
                     // We know the type is inhabited, so this must be wrong
                     let mut err = create_e0004(self.tcx.sess, scrut.span,
-                                               format!("non-exhaustive patterns: type {} \
+                                               format!("non-exhaustive patterns: type `{}` \
                                                         is non-empty",
                                                        pat_ty));
                     span_help!(&mut err, scrut.span,
diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs
index 617d204fe1042..300f3d639b588 100644
--- a/src/librustc_mir/interpret/terminator.rs
+++ b/src/librustc_mir/interpret/terminator.rs
@@ -182,6 +182,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
     }
 
     fn check_argument_compat(
+        rust_abi: bool,
         caller: TyLayout<'tcx>,
         callee: TyLayout<'tcx>,
     ) -> bool {
@@ -189,13 +190,20 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
             // No question
             return true;
         }
+        if !rust_abi {
+            // Don't risk anything
+            return false;
+        }
         // Compare layout
         match (&caller.abi, &callee.abi) {
+            // Different valid ranges are okay (once we enforce validity,
+            // that will take care to make it UB to leave the range, just
+            // like for transmute).
             (layout::Abi::Scalar(ref caller), layout::Abi::Scalar(ref callee)) =>
-                // Different valid ranges are okay (once we enforce validity,
-                // that will take care to make it UB to leave the range, just
-                // like for transmute).
                 caller.value == callee.value,
+            (layout::Abi::ScalarPair(ref caller1, ref caller2),
+             layout::Abi::ScalarPair(ref callee1, ref callee2)) =>
+                caller1.value == callee1.value && caller2.value == callee2.value,
             // Be conservative
             _ => false
         }
@@ -204,22 +212,22 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
     /// Pass a single argument, checking the types for compatibility.
     fn pass_argument(
         &mut self,
-        skip_zst: bool,
+        rust_abi: bool,
         caller_arg: &mut impl Iterator<Item=OpTy<'tcx, M::PointerTag>>,
         callee_arg: PlaceTy<'tcx, M::PointerTag>,
     ) -> EvalResult<'tcx> {
-        if skip_zst && callee_arg.layout.is_zst() {
+        if rust_abi && callee_arg.layout.is_zst() {
             // Nothing to do.
             trace!("Skipping callee ZST");
             return Ok(());
         }
         let caller_arg = caller_arg.next()
             .ok_or_else(|| EvalErrorKind::FunctionArgCountMismatch)?;
-        if skip_zst {
+        if rust_abi {
             debug_assert!(!caller_arg.layout.is_zst(), "ZSTs must have been already filtered out");
         }
         // Now, check
-        if !Self::check_argument_compat(caller_arg.layout, callee_arg.layout) {
+        if !Self::check_argument_compat(rust_abi, caller_arg.layout, callee_arg.layout) {
             return err!(FunctionArgMismatch(caller_arg.layout.ty, callee_arg.layout.ty));
         }
         // We allow some transmutes here
@@ -319,7 +327,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
                     // Figure out how to pass which arguments.
                     // We have two iterators: Where the arguments come from,
                     // and where they go to.
-                    let skip_zst = match caller_abi {
+                    let rust_abi = match caller_abi {
                         Abi::Rust | Abi::RustCall => true,
                         _ => false
                     };
@@ -344,7 +352,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
                         };
                     // Skip ZSTs
                     let mut caller_iter = caller_args.iter()
-                        .filter(|op| !skip_zst || !op.layout.is_zst())
+                        .filter(|op| !rust_abi || !op.layout.is_zst())
                         .map(|op| *op);
 
                     // Now we have to spread them out across the callee's locals,
@@ -359,11 +367,11 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
                             // Must be a tuple
                             for i in 0..dest.layout.fields.count() {
                                 let dest = self.place_field(dest, i as u64)?;
-                                self.pass_argument(skip_zst, &mut caller_iter, dest)?;
+                                self.pass_argument(rust_abi, &mut caller_iter, dest)?;
                             }
                         } else {
                             // Normal argument
-                            self.pass_argument(skip_zst, &mut caller_iter, dest)?;
+                            self.pass_argument(rust_abi, &mut caller_iter, dest)?;
                         }
                     }
                     // Now we should have no more caller args
@@ -374,7 +382,11 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
                     // Don't forget to check the return type!
                     if let Some(caller_ret) = dest {
                         let callee_ret = self.eval_place(&mir::Place::Local(mir::RETURN_PLACE))?;
-                        if !Self::check_argument_compat(caller_ret.layout, callee_ret.layout) {
+                        if !Self::check_argument_compat(
+                            rust_abi,
+                            caller_ret.layout,
+                            callee_ret.layout,
+                        ) {
                             return err!(FunctionRetMismatch(
                                 caller_ret.layout.ty, callee_ret.layout.ty
                             ));
diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs
index 6dba020120f84..3a6ee6da42215 100644
--- a/src/librustc_mir/monomorphize/partitioning.rs
+++ b/src/librustc_mir/monomorphize/partitioning.rs
@@ -985,7 +985,7 @@ fn collect_and_partition_mono_items<'a, 'tcx>(
                 output.push_str(" @@");
                 let mut empty = Vec::new();
                 let cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);
-                cgus.as_mut_slice().sort_by_key(|&(ref name, _)| name.clone());
+                cgus.as_mut_slice().sort_by_cached_key(|&(ref name, _)| name.clone());
                 cgus.dedup();
                 for &(ref cgu_name, (linkage, _)) in cgus.iter() {
                     output.push_str(" ");
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 93bf1b3e36e38..04079319a7877 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -226,8 +226,13 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         // The first argument (index 0), but add 1 for the return value.
         let dropee_ptr = Place::Local(Local::new(1+0));
         if tcx.sess.opts.debugging_opts.mir_emit_retag {
-            // We use raw ptr operations, better prepare the alias tracking for that
+            // Function arguments should be retagged
             mir.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement {
+                source_info,
+                kind: StatementKind::Retag { fn_entry: true, place: dropee_ptr.clone() },
+            });
+            // We use raw ptr operations, better prepare the alias tracking for that
+            mir.basic_blocks_mut()[START_BLOCK].statements.insert(1, Statement {
                 source_info,
                 kind: StatementKind::EscapeToRaw(Operand::Copy(dropee_ptr.clone())),
             })
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index fc2c6c3ab1f37..09fe7b14c7973 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -357,7 +357,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
                 TerminatorKind::FalseUnwind { .. } => None,
 
                 TerminatorKind::Return => {
-                    if !self.tcx.sess.features_untracked().const_let {
+                    if !self.tcx.features().const_let {
                         // Check for unused values. This usually means
                         // there are extra statements in the AST.
                         for temp in mir.temps_iter() {
@@ -464,7 +464,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
             LocalKind::ReturnPointer => {
                 self.not_const();
             }
-            LocalKind::Var if !self.tcx.sess.features_untracked().const_let => {
+            LocalKind::Var if !self.tcx.features().const_let => {
                 if self.mode != Mode::Fn {
                     emit_feature_err(&self.tcx.sess.parse_sess, "const_let",
                                     self.span, GateIssue::Language,
@@ -558,7 +558,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                                 Mode::Fn => {},
                                 _ => {
                                     if let ty::RawPtr(_) = base_ty.sty {
-                                        if !this.tcx.sess.features_untracked().const_raw_ptr_deref {
+                                        if !this.tcx.features().const_raw_ptr_deref {
                                             emit_feature_err(
                                                 &this.tcx.sess.parse_sess, "const_raw_ptr_deref",
                                                 this.span, GateIssue::Language,
@@ -581,7 +581,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                                     match this.mode {
                                         Mode::Fn => this.not_const(),
                                         Mode::ConstFn => {
-                                            if !this.tcx.sess.features_untracked().const_fn_union {
+                                            if !this.tcx.features().const_fn_union {
                                                 emit_feature_err(
                                                     &this.tcx.sess.parse_sess, "const_fn_union",
                                                     this.span, GateIssue::Language,
@@ -807,7 +807,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                         if let Mode::Fn = self.mode {
                             // in normal functions, mark such casts as not promotable
                             self.add(Qualif::NOT_CONST);
-                        } else if !self.tcx.sess.features_untracked().const_raw_ptr_to_usize_cast {
+                        } else if !self.tcx.features().const_raw_ptr_to_usize_cast {
                             // in const fn and constants require the feature gate
                             // FIXME: make it unsafe inside const fn and constants
                             emit_feature_err(
@@ -834,7 +834,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                     if let Mode::Fn = self.mode {
                         // raw pointer operations are not allowed inside promoteds
                         self.add(Qualif::NOT_CONST);
-                    } else if !self.tcx.sess.features_untracked().const_compare_raw_pointers {
+                    } else if !self.tcx.features().const_compare_raw_pointers {
                         // require the feature gate inside constants and const fn
                         // FIXME: make it unsafe to use these operations
                         emit_feature_err(
@@ -933,7 +933,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                                 if self.mode != Mode::Fn {
                                     is_const_fn = true;
                                     // const eval transmute calls only with the feature gate
-                                    if !self.tcx.sess.features_untracked().const_transmute {
+                                    if !self.tcx.features().const_transmute {
                                         emit_feature_err(
                                             &self.tcx.sess.parse_sess, "const_transmute",
                                             self.span, GateIssue::Language,
@@ -971,7 +971,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                                 // FIXME: cannot allow this inside `allow_internal_unstable` because
                                 // that would make `panic!` insta stable in constants, since the
                                 // macro is marked with the attr
-                                if self.tcx.sess.features_untracked().const_panic {
+                                if self.tcx.features().const_panic {
                                     is_const_fn = true;
                                 } else {
                                     // don't allow panics in constants without the feature gate
@@ -1158,7 +1158,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
         if let (Mode::ConstFn, &Place::Local(index)) = (self.mode, dest) {
             if self.mir.local_kind(index) == LocalKind::Var &&
                self.const_fn_arg_vars.insert(index) &&
-               !self.tcx.sess.features_untracked().const_let {
+               !self.tcx.features().const_let {
 
                 // Direct use of an argument is permitted.
                 match *rvalue {
diff --git a/src/librustc_target/README.md b/src/librustc_target/README.md
index f5b1acb192133..a22000ea9d280 100644
--- a/src/librustc_target/README.md
+++ b/src/librustc_target/README.md
@@ -3,4 +3,4 @@ specific to different compilation targets and so forth.
 
 For more information about how rustc works, see the [rustc guide].
 
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/
+[rustc guide]: https://rust-lang.github.io/rustc-guide/
diff --git a/src/librustc_typeck/README.md b/src/librustc_typeck/README.md
index f00597cb27f0c..fdcbd935524db 100644
--- a/src/librustc_typeck/README.md
+++ b/src/librustc_typeck/README.md
@@ -1,5 +1,5 @@
 For high-level intro to how type checking works in rustc, see the
 [type checking] chapter of the [rustc guide].
 
-[type checking]: https://rust-lang-nursery.github.io/rustc-guide/type-checking.html
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/
+[type checking]: https://rust-lang.github.io/rustc-guide/type-checking.html
+[rustc guide]: https://rust-lang.github.io/rustc-guide/
diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs
index 73489309d0742..2cd2bb5064877 100644
--- a/src/librustc_typeck/check/autoderef.rs
+++ b/src/librustc_typeck/check/autoderef.rs
@@ -59,7 +59,7 @@ impl<'a, 'gcx, 'tcx> Iterator for Autoderef<'a, 'gcx, 'tcx> {
         if self.steps.len() >= *tcx.sess.recursion_limit.get() {
             // We've reached the recursion limit, error gracefully.
             let suggested_limit = *tcx.sess.recursion_limit.get() * 2;
-            let msg = format!("reached the recursion limit while auto-dereferencing {:?}",
+            let msg = format!("reached the recursion limit while auto-dereferencing `{:?}`",
                               self.cur_ty);
             let error_id = (DiagnosticMessageId::ErrorId(55), Some(self.span), msg);
             let fresh = tcx.sess.one_time_diagnostics.borrow_mut().insert(error_id);
@@ -67,7 +67,7 @@ impl<'a, 'gcx, 'tcx> Iterator for Autoderef<'a, 'gcx, 'tcx> {
                 struct_span_err!(tcx.sess,
                                  self.span,
                                  E0055,
-                                 "reached the recursion limit while auto-dereferencing {:?}",
+                                 "reached the recursion limit while auto-dereferencing `{:?}`",
                                  self.cur_ty)
                     .span_label(self.span, "deref recursion limit reached")
                     .help(&format!(
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index ac338ba667865..37f4ae56779b2 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -10,7 +10,7 @@
 
 //! Method lookup: the secret sauce of Rust. See the [rustc guide] chapter.
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/method-lookup.html
+//! [rustc guide]: https://rust-lang.github.io/rustc-guide/method-lookup.html
 
 use check::FnCtxt;
 use hir::def::Def;
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index a985c3e9fdf44..084951f4a2c16 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -538,7 +538,7 @@ fn main() {
     let foo = Foo;
     let ref_foo = &&Foo;
 
-    // error, reached the recursion limit while auto-dereferencing &&Foo
+    // error, reached the recursion limit while auto-dereferencing `&&Foo`
     ref_foo.foo();
 }
 ```
diff --git a/src/librustc_typeck/variance/mod.rs b/src/librustc_typeck/variance/mod.rs
index 7cc56bc192bb2..e3c82d50a8d9b 100644
--- a/src/librustc_typeck/variance/mod.rs
+++ b/src/librustc_typeck/variance/mod.rs
@@ -11,7 +11,7 @@
 //! Module for inferring the variance of type and lifetime parameters. See the [rustc guide]
 //! chapter for more info.
 //!
-//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/variance.html
+//! [rustc guide]: https://rust-lang.github.io/rustc-guide/variance.html
 
 use arena;
 use rustc::hir;
diff --git a/src/librustc_typeck/variance/terms.rs b/src/librustc_typeck/variance/terms.rs
index 087d53b92d496..3692221a3fc3f 100644
--- a/src/librustc_typeck/variance/terms.rs
+++ b/src/librustc_typeck/variance/terms.rs
@@ -89,8 +89,8 @@ pub fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>
 
     // See the following for a discussion on dep-graph management.
     //
-    // - https://rust-lang-nursery.github.io/rustc-guide/query.html
-    // - https://rust-lang-nursery.github.io/rustc-guide/variance.html
+    // - https://rust-lang.github.io/rustc-guide/query.html
+    // - https://rust-lang.github.io/rustc-guide/variance.html
     tcx.hir.krate().visit_all_item_likes(&mut terms_cx);
 
     terms_cx
diff --git a/src/librustdoc/README.md b/src/librustdoc/README.md
index 2cfe43a8389bb..e4f7bc30e3fcf 100644
--- a/src/librustdoc/README.md
+++ b/src/librustdoc/README.md
@@ -1,3 +1,3 @@
 For more information about how `librustdoc` works, see the [rustc guide].
 
-[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/rustdoc.html
+[rustc guide]: https://rust-lang.github.io/rustc-guide/rustdoc.html
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index f4d05c6dbd65c..b421f07ddafa2 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -20,7 +20,7 @@ use rustc::session::early_error;
 use rustc::session::config::{CodegenOptions, DebuggingOptions, ErrorOutputType, Externs};
 use rustc::session::config::{nightly_options, build_codegen_options, build_debugging_options,
                              get_cmd_lint_options};
-use rustc::session::search_paths::SearchPaths;
+use rustc::session::search_paths::SearchPath;
 use rustc_driver;
 use rustc_target::spec::TargetTriple;
 use syntax::edition::Edition;
@@ -46,7 +46,7 @@ pub struct Options {
     /// How to format errors and warnings.
     pub error_format: ErrorOutputType,
     /// Library search paths to hand to the compiler.
-    pub libs: SearchPaths,
+    pub libs: Vec<SearchPath>,
     /// The list of external crates to link against.
     pub externs: Externs,
     /// List of `cfg` flags to hand to the compiler. Always includes `rustdoc`.
@@ -295,10 +295,9 @@ impl Options {
         }
         let input = PathBuf::from(&matches.free[0]);
 
-        let mut libs = SearchPaths::new();
-        for s in &matches.opt_strs("L") {
-            libs.add_path(s, error_format);
-        }
+        let libs = matches.opt_strs("L").iter()
+            .map(|s| SearchPath::from_cli_opt(s, error_format))
+            .collect();
         let externs = match parse_externs(&matches) {
             Ok(ex) => ex,
             Err(err) => {
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index aac0f9f94e329..9502993ed243c 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -51,7 +51,7 @@ use html::render::RenderInfo;
 use passes;
 
 pub use rustc::session::config::{Input, Options, CodegenOptions};
-pub use rustc::session::search_paths::SearchPaths;
+pub use rustc::session::search_paths::SearchPath;
 
 pub type ExternalPaths = FxHashMap<DefId, (Vec<String>, clean::TypeKind)>;
 
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index d9bab91fd0c78..918fdc1f38a48 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -25,7 +25,7 @@ use rustc::hir;
 use rustc::hir::intravisit;
 use rustc::session::{self, CompileIncomplete, config};
 use rustc::session::config::{OutputType, OutputTypes, Externs, CodegenOptions};
-use rustc::session::search_paths::{SearchPaths, PathKind};
+use rustc::session::search_paths::{SearchPath, PathKind};
 use rustc_metadata::dynamic_lib::DynamicLibrary;
 use tempfile::Builder as TempFileBuilder;
 use rustc_driver::{self, driver, target_features, Compilation};
@@ -187,7 +187,7 @@ fn scrape_test_config(krate: &::rustc::hir::Crate) -> TestOptions {
 }
 
 fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize,
-            cfgs: Vec<String>, libs: SearchPaths,
+            cfgs: Vec<String>, libs: Vec<SearchPath>,
             cg: CodegenOptions, externs: Externs,
             should_panic: bool, no_run: bool, as_test_harness: bool,
             compile_fail: bool, mut error_codes: Vec<String>, opts: &TestOptions,
@@ -557,7 +557,7 @@ pub struct Collector {
     names: Vec<String>,
 
     cfgs: Vec<String>,
-    libs: SearchPaths,
+    libs: Vec<SearchPath>,
     cg: CodegenOptions,
     externs: Externs,
     use_headers: bool,
@@ -572,7 +572,7 @@ pub struct Collector {
 }
 
 impl Collector {
-    pub fn new(cratename: String, cfgs: Vec<String>, libs: SearchPaths, cg: CodegenOptions,
+    pub fn new(cratename: String, cfgs: Vec<String>, libs: Vec<SearchPath>, cg: CodegenOptions,
                externs: Externs, use_headers: bool, opts: TestOptions,
                maybe_sysroot: Option<PathBuf>, source_map: Option<Lrc<SourceMap>>,
                filename: Option<PathBuf>, linker: Option<PathBuf>, edition: Edition) -> Collector {
diff --git a/src/libserialize/collection_impls.rs b/src/libserialize/collection_impls.rs
index 3e028d755c6d4..cbd642dd6ad91 100644
--- a/src/libserialize/collection_impls.rs
+++ b/src/libserialize/collection_impls.rs
@@ -86,7 +86,7 @@ impl<T: Encodable> Encodable for VecDeque<T> {
 impl<T:Decodable> Decodable for VecDeque<T> {
     fn decode<D: Decoder>(d: &mut D) -> Result<VecDeque<T>, D::Error> {
         d.read_seq(|d, len| {
-            let mut deque: VecDeque<T> = VecDeque::new();
+            let mut deque: VecDeque<T> = VecDeque::with_capacity(len);
             for i in 0..len {
                 deque.push_back(d.read_seq_elt(i, |d| Decodable::decode(d))?);
             }
diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs
index a3345df5e0d85..f1f3742996bda 100644
--- a/src/libstd/ffi/mod.rs
+++ b/src/libstd/ffi/mod.rs
@@ -112,12 +112,12 @@
 //! ## On Unix
 //!
 //! On Unix, [`OsStr`] implements the
-//! `std::os::unix:ffi::`[`OsStrExt`][unix.OsStrExt] trait, which
+//! `std::os::unix::ffi::`[`OsStrExt`][unix.OsStrExt] trait, which
 //! augments it with two methods, [`from_bytes`] and [`as_bytes`].
 //! These do inexpensive conversions from and to UTF-8 byte slices.
 //!
 //! Additionally, on Unix [`OsString`] implements the
-//! `std::os::unix:ffi::`[`OsStringExt`][unix.OsStringExt] trait,
+//! `std::os::unix::ffi::`[`OsStringExt`][unix.OsStringExt] trait,
 //! which provides [`from_vec`] and [`into_vec`] methods that consume
 //! their arguments, and take or produce vectors of [`u8`].
 //!
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index e263db24fc2c8..076524e624a47 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -431,7 +431,7 @@ fn read_to_end_with_reservation<R: Read + ?Sized>(r: &mut R,
 ///     // read up to 10 bytes
 ///     f.read(&mut buffer)?;
 ///
-///     let mut buffer = vec![0; 10];
+///     let mut buffer = Vec::new();
 ///     // read the whole file
 ///     f.read_to_end(&mut buffer)?;
 ///
diff --git a/src/libstd/os/linux/fs.rs b/src/libstd/os/linux/fs.rs
index 76fb10da850b1..b518f524e0b08 100644
--- a/src/libstd/os/linux/fs.rs
+++ b/src/libstd/os/linux/fs.rs
@@ -191,7 +191,7 @@ pub trait MetadataExt {
     /// ```
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_size(&self) -> u64;
-    /// Returns the last access time.
+    /// Returns the last access time of the file, in seconds since Unix Epoch.
     ///
     /// # Examples
     ///
@@ -208,7 +208,9 @@ pub trait MetadataExt {
     /// ```
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_atime(&self) -> i64;
-    /// Returns the last access time, nano seconds part.
+    /// Returns the last access time of the file, in nanoseconds since [`st_atime`].
+    ///
+    /// [`st_atime`]: #tymethod.st_atime
     ///
     /// # Examples
     ///
@@ -225,7 +227,7 @@ pub trait MetadataExt {
     /// ```
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_atime_nsec(&self) -> i64;
-    /// Returns the last modification time.
+    /// Returns the last modification time of the file, in seconds since Unix Epoch.
     ///
     /// # Examples
     ///
@@ -242,7 +244,9 @@ pub trait MetadataExt {
     /// ```
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_mtime(&self) -> i64;
-    /// Returns the last modification time, nano seconds part.
+    /// Returns the last modification time of the file, in nanoseconds since [`st_mtime`].
+    ///
+    /// [`st_mtime`]: #tymethod.st_mtime
     ///
     /// # Examples
     ///
@@ -259,7 +263,7 @@ pub trait MetadataExt {
     /// ```
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_mtime_nsec(&self) -> i64;
-    /// Returns the last status change time.
+    /// Returns the last status change time of the file, in seconds since Unix Epoch.
     ///
     /// # Examples
     ///
@@ -276,7 +280,9 @@ pub trait MetadataExt {
     /// ```
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_ctime(&self) -> i64;
-    /// Returns the last status change time, nano seconds part.
+    /// Returns the last status change time of the file, in nanoseconds since [`st_ctime`].
+    ///
+    /// [`st_ctime`]: #tymethod.st_ctime
     ///
     /// # Examples
     ///
diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs
index 507e9d881717b..7e65bbdef2a96 100644
--- a/src/libstd/sys/unix/ext/fs.rs
+++ b/src/libstd/sys/unix/ext/fs.rs
@@ -522,7 +522,7 @@ pub trait MetadataExt {
     /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn size(&self) -> u64;
-    /// Returns the time of the last access to the file.
+    /// Returns the last access time of the file, in seconds since Unix Epoch.
     ///
     /// # Examples
     ///
@@ -539,7 +539,9 @@ pub trait MetadataExt {
     /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn atime(&self) -> i64;
-    /// Returns the time of the last access to the file in nanoseconds.
+    /// Returns the last access time of the file, in nanoseconds since [`atime`].
+    ///
+    /// [`atime`]: #tymethod.atime
     ///
     /// # Examples
     ///
@@ -556,7 +558,7 @@ pub trait MetadataExt {
     /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn atime_nsec(&self) -> i64;
-    /// Returns the time of the last modification of the file.
+    /// Returns the last modification time of the file, in seconds since Unix Epoch.
     ///
     /// # Examples
     ///
@@ -573,7 +575,9 @@ pub trait MetadataExt {
     /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn mtime(&self) -> i64;
-    /// Returns the time of the last modification of the file in nanoseconds.
+    /// Returns the last modification time of the file, in nanoseconds since [`mtime`].
+    ///
+    /// [`mtime`]: #tymethod.mtime
     ///
     /// # Examples
     ///
@@ -590,7 +594,7 @@ pub trait MetadataExt {
     /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn mtime_nsec(&self) -> i64;
-    /// Returns the time of the last status change of the file.
+    /// Returns the last status change time of the file, in seconds since Unix Epoch.
     ///
     /// # Examples
     ///
@@ -607,7 +611,9 @@ pub trait MetadataExt {
     /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn ctime(&self) -> i64;
-    /// Returns the time of the last status change of the file in nanoseconds.
+    /// Returns the last status change time of the file, in nanoseconds since [`ctime`].
+    ///
+    /// [`ctime`]: #tymethod.ctime
     ///
     /// # Examples
     ///
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 8a845efd41362..3a9f3ec5c6fc1 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -326,7 +326,7 @@ impl Builder {
     /// Sets the size of the stack (in bytes) for the new thread.
     ///
     /// The actual stack size may be greater than this value if
-    /// the platform specifies minimal stack size.
+    /// the platform specifies a minimal stack size.
     ///
     /// For more information about the stack size for threads, see
     /// [this module-level documentation][stack-size].
diff --git a/src/libsyntax/README.md b/src/libsyntax/README.md
index 7214203830e74..daa252ef4551b 100644
--- a/src/libsyntax/README.md
+++ b/src/libsyntax/README.md
@@ -5,5 +5,5 @@ lexer, macro expander, and utilities for traversing ASTs.
 For more information about how these things work in rustc, see the
 rustc guide:
 
-- [Parsing](https://rust-lang-nursery.github.io/rustc-guide/the-parser.html)
-- [Macro Expansion](https://rust-lang-nursery.github.io/rustc-guide/macro-expansion.html)
+- [Parsing](https://rust-lang.github.io/rustc-guide/the-parser.html)
+- [Macro Expansion](https://rust-lang.github.io/rustc-guide/macro-expansion.html)
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index cc8af70a050c9..68a96293891a0 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -1201,50 +1201,62 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
 
 impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
     fn fold_expr(&mut self, expr: P<ast::Expr>) -> P<ast::Expr> {
-        let mut expr = self.cfg.configure_expr(expr).into_inner();
-        expr.node = self.cfg.configure_expr_kind(expr.node);
-
-        // ignore derives so they remain unused
-        let (attr, expr, after_derive) = self.classify_nonitem(expr);
-
-        if attr.is_some() {
-            // collect the invoc regardless of whether or not attributes are permitted here
-            // expansion will eat the attribute so it won't error later
-            attr.as_ref().map(|a| self.cfg.maybe_emit_expr_attr_err(a));
-
-            // AstFragmentKind::Expr requires the macro to emit an expression
-            return self.collect_attr(attr, vec![], Annotatable::Expr(P(expr)),
-                                     AstFragmentKind::Expr, after_derive).make_expr();
-        }
+        let expr = self.cfg.configure_expr(expr);
+        expr.map(|mut expr| {
+            expr.node = self.cfg.configure_expr_kind(expr.node);
+
+            // ignore derives so they remain unused
+            let (attr, expr, after_derive) = self.classify_nonitem(expr);
+
+            if attr.is_some() {
+                // Collect the invoc regardless of whether or not attributes are permitted here
+                // expansion will eat the attribute so it won't error later.
+                attr.as_ref().map(|a| self.cfg.maybe_emit_expr_attr_err(a));
+
+                // AstFragmentKind::Expr requires the macro to emit an expression.
+                return self.collect_attr(attr, vec![], Annotatable::Expr(P(expr)),
+                                         AstFragmentKind::Expr, after_derive)
+                    .make_expr()
+                    .into_inner()
+            }
 
-        if let ast::ExprKind::Mac(mac) = expr.node {
-            self.check_attributes(&expr.attrs);
-            self.collect_bang(mac, expr.span, AstFragmentKind::Expr).make_expr()
-        } else {
-            P(noop_fold_expr(expr, self))
-        }
+            if let ast::ExprKind::Mac(mac) = expr.node {
+                self.check_attributes(&expr.attrs);
+                self.collect_bang(mac, expr.span, AstFragmentKind::Expr)
+                    .make_expr()
+                    .into_inner()
+            } else {
+                noop_fold_expr(expr, self)
+            }
+        })
     }
 
     fn fold_opt_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
-        let mut expr = configure!(self, expr).into_inner();
-        expr.node = self.cfg.configure_expr_kind(expr.node);
+        let expr = configure!(self, expr);
+        expr.filter_map(|mut expr| {
+            expr.node = self.cfg.configure_expr_kind(expr.node);
 
-        // ignore derives so they remain unused
-        let (attr, expr, after_derive) = self.classify_nonitem(expr);
+            // Ignore derives so they remain unused.
+            let (attr, expr, after_derive) = self.classify_nonitem(expr);
 
-        if attr.is_some() {
-            attr.as_ref().map(|a| self.cfg.maybe_emit_expr_attr_err(a));
+            if attr.is_some() {
+                attr.as_ref().map(|a| self.cfg.maybe_emit_expr_attr_err(a));
 
-            return self.collect_attr(attr, vec![], Annotatable::Expr(P(expr)),
-                                     AstFragmentKind::OptExpr, after_derive).make_opt_expr();
-        }
+                return self.collect_attr(attr, vec![], Annotatable::Expr(P(expr)),
+                                         AstFragmentKind::OptExpr, after_derive)
+                    .make_opt_expr()
+                    .map(|expr| expr.into_inner())
+            }
 
-        if let ast::ExprKind::Mac(mac) = expr.node {
-            self.check_attributes(&expr.attrs);
-            self.collect_bang(mac, expr.span, AstFragmentKind::OptExpr).make_opt_expr()
-        } else {
-            Some(P(noop_fold_expr(expr, self)))
-        }
+            if let ast::ExprKind::Mac(mac) = expr.node {
+                self.check_attributes(&expr.attrs);
+                self.collect_bang(mac, expr.span, AstFragmentKind::OptExpr)
+                    .make_opt_expr()
+                    .map(|expr| expr.into_inner())
+            } else {
+                Some(noop_fold_expr(expr, self))
+            }
+        })
     }
 
     fn fold_pat(&mut self, pat: P<ast::Pat>) -> P<ast::Pat> {
diff --git a/src/libsyntax/ext/tt/quoted.rs b/src/libsyntax/ext/tt/quoted.rs
index 218486748315d..edc431be3694b 100644
--- a/src/libsyntax/ext/tt/quoted.rs
+++ b/src/libsyntax/ext/tt/quoted.rs
@@ -11,13 +11,13 @@
 use ast::NodeId;
 use early_buffered_lints::BufferedEarlyLintId;
 use ext::tt::macro_parser;
-use feature_gate::{self, emit_feature_err, Features, GateIssue};
+use feature_gate::Features;
 use parse::{token, ParseSess};
 use print::pprust;
 use symbol::keywords;
 use syntax_pos::{edition::Edition, BytePos, Span};
 use tokenstream::{self, DelimSpan};
-use {ast, attr};
+use ast;
 
 use rustc_data_structures::sync::Lrc;
 use std::iter::Peekable;
@@ -566,8 +566,8 @@ fn parse_sep_and_kleene_op_2018<I>(
     input: &mut Peekable<I>,
     span: Span,
     sess: &ParseSess,
-    features: &Features,
-    attrs: &[ast::Attribute],
+    _features: &Features,
+    _attrs: &[ast::Attribute],
 ) -> (Option<token::Token>, KleeneOp)
 where
     I: Iterator<Item = tokenstream::TokenTree>,
@@ -575,23 +575,8 @@ where
     // We basically look at two token trees here, denoted as #1 and #2 below
     let span = match parse_kleene_op(input, span) {
         // #1 is a `?` (needs feature gate)
-        Ok(Ok((op, op1_span))) 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",
-                    op1_span,
-                    GateIssue::Language,
-                    explain,
-                );
-
-                op1_span
-            } else {
-                return (None, op);
-            }
+        Ok(Ok((op, _op1_span))) if op == KleeneOp::ZeroOrOne => {
+            return (None, op);
         }
 
         // #1 is a `+` or `*` KleeneOp
@@ -600,24 +585,12 @@ where
         // #1 is a separator followed by #2, a KleeneOp
         Ok(Err((tok, span))) => match parse_kleene_op(input, span) {
             // #2 is the `?` Kleene op, which does not take a separator (error)
-            Ok(Ok((op, op2_span))) if op == KleeneOp::ZeroOrOne => {
+            Ok(Ok((op, _op2_span))) if op == KleeneOp::ZeroOrOne => {
                 // Error!
-
-                if !features.macro_at_most_once_rep
-                    && !attr::contains_name(attrs, "allow_internal_unstable")
-                {
-                    // FIXME: when `?` as a Kleene op is stabilized, we only need the "does not
-                    // take a macro separator" error (i.e. the `else` case).
-                    sess.span_diagnostic
-                        .struct_span_err(op2_span, "expected `*` or `+`")
-                        .note("`?` is not a macro repetition operator")
-                        .emit();
-                } else {
-                    sess.span_diagnostic.span_err(
-                        span,
-                        "the `?` macro repetition operator does not take a separator",
-                    );
-                }
+                sess.span_diagnostic.span_err(
+                    span,
+                    "the `?` macro repetition operator does not take a separator",
+                );
 
                 // Return a dummy
                 return (None, KleeneOp::ZeroOrMore);
@@ -638,13 +611,8 @@ where
     };
 
     // If we ever get to this point, we have experienced an "unexpected token" error
-
-    if !features.macro_at_most_once_rep && !attr::contains_name(attrs, "allow_internal_unstable") {
-        sess.span_diagnostic.span_err(span, "expected `*` or `+`");
-    } else {
-        sess.span_diagnostic
-            .span_err(span, "expected one of: `*`, `+`, or `?`");
-    }
+    sess.span_diagnostic
+        .span_err(span, "expected one of: `*`, `+`, or `?`");
 
     // Return a dummy
     (None, KleeneOp::ZeroOrMore)
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 73567765a04c4..3bc349170514c 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -393,9 +393,6 @@ declare_features! (
     // `extern` in paths
     (active, extern_in_paths, "1.23.0", Some(55600), None),
 
-    // Use `?` as the Kleene "at most one" operator
-    (active, macro_at_most_once_rep, "1.25.0", Some(48075), None),
-
     // Infer static outlives requirements; RFC 2093
     (active, infer_static_outlives_requirements, "1.26.0", Some(54185), None),
 
@@ -689,6 +686,8 @@ declare_features! (
     (accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None),
     // Allows use of the :literal macro fragment specifier (RFC 1576)
     (accepted, macro_literal_matcher, "1.31.0", Some(35625), None),
+    // Use `?` as the Kleene "at most one" operator
+    (accepted, macro_at_most_once_rep, "1.32.0", Some(48075), None),
 );
 
 // If you change this, please modify src/doc/unstable-book as well. You must
@@ -1427,9 +1426,6 @@ pub const EXPLAIN_DERIVE_UNDERSCORE: &'static str =
 pub const EXPLAIN_UNSIZED_TUPLE_COERCION: &'static str =
     "unsized tuple coercion is not stable enough for use and is subject to change";
 
-pub const EXPLAIN_MACRO_AT_MOST_ONCE_REP: &'static str =
-    "using the `?` macro Kleene operator for \"at most one\" repetition is unstable";
-
 struct PostExpansionVisitor<'a> {
     context: &'a Context<'a>,
 }
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 9bbd59e09be15..ca9c5ad7b600e 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -20,7 +20,6 @@
        test(attr(deny(warnings))))]
 
 #![feature(crate_visibility_modifier)]
-#![feature(macro_at_most_once_rep)]
 #![feature(nll)]
 #![feature(rustc_attrs)]
 #![feature(rustc_diagnostic_macros)]
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index 0584cd5a3df47..c90c62c13f969 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -60,11 +60,11 @@ pub struct StringReader<'a> {
     // cache a direct reference to the source text, so that we don't have to
     // retrieve it via `self.source_file.src.as_ref().unwrap()` all the time.
     src: Lrc<String>,
-    /// Stack of open delimiters and their spans. Used for error message.
     token: token::Token,
     span: Span,
     /// The raw source span which *does not* take `override_span` into account
     span_src_raw: Span,
+    /// Stack of open delimiters and their spans. Used for error message.
     open_braces: Vec<(token::DelimToken, Span)>,
     /// The type and spans for all braces
     ///
@@ -506,8 +506,7 @@ impl<'a> StringReader<'a> {
         }
     }
 
-    /// Advance the StringReader by one character. If a newline is
-    /// discovered, add it to the SourceFile's list of line start offsets.
+    /// Advance the StringReader by one character.
     crate fn bump(&mut self) {
         let next_src_index = self.src_index(self.next_pos);
         if next_src_index < self.end_src_index {
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index c82ebd6aa5128..e0436cc7380ab 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -5172,8 +5172,12 @@ impl<'a> Parser<'a> {
     /// Parses (possibly empty) list of lifetime and type parameters, possibly including
     /// trailing comma and erroneous trailing attributes.
     crate fn parse_generic_params(&mut self) -> PResult<'a, Vec<ast::GenericParam>> {
+        let mut lifetimes = Vec::new();
         let mut params = Vec::new();
-        let mut seen_ty_param = false;
+        let mut seen_ty_param: Option<Span> = None;
+        let mut last_comma_span = None;
+        let mut bad_lifetime_pos = vec![];
+        let mut suggestions = vec![];
         loop {
             let attrs = self.parse_outer_attributes()?;
             if self.check_lifetime() {
@@ -5184,25 +5188,42 @@ impl<'a> Parser<'a> {
                 } else {
                     Vec::new()
                 };
-                params.push(ast::GenericParam {
+                lifetimes.push(ast::GenericParam {
                     ident: lifetime.ident,
                     id: lifetime.id,
                     attrs: attrs.into(),
                     bounds,
                     kind: ast::GenericParamKind::Lifetime,
                 });
-                if seen_ty_param {
-                    self.span_err(self.prev_span,
-                        "lifetime parameters must be declared prior to type parameters");
+                if let Some(sp) = seen_ty_param {
+                    let param_span = self.prev_span;
+                    let ate_comma = self.eat(&token::Comma);
+                    let remove_sp = if ate_comma {
+                        param_span.until(self.span)
+                    } else {
+                        last_comma_span.unwrap_or(param_span).to(param_span)
+                    };
+                    bad_lifetime_pos.push(param_span);
+
+                    if let Ok(snippet) = self.sess.source_map().span_to_snippet(param_span) {
+                        suggestions.push((remove_sp, String::new()));
+                        suggestions.push((sp.shrink_to_lo(), format!("{}, ", snippet)));
+                    }
+                    if ate_comma {
+                        last_comma_span = Some(self.prev_span);
+                        continue
+                    }
                 }
             } else if self.check_ident() {
                 // Parse type parameter.
                 params.push(self.parse_ty_param(attrs)?);
-                seen_ty_param = true;
+                if seen_ty_param.is_none() {
+                    seen_ty_param = Some(self.prev_span);
+                }
             } else {
                 // Check for trailing attributes and stop parsing.
                 if !attrs.is_empty() {
-                    let param_kind = if seen_ty_param { "type" } else { "lifetime" };
+                    let param_kind = if seen_ty_param.is_some() { "type" } else { "lifetime" };
                     self.span_err(attrs[0].span,
                         &format!("trailing attribute after {} parameters", param_kind));
                 }
@@ -5212,8 +5233,24 @@ impl<'a> Parser<'a> {
             if !self.eat(&token::Comma) {
                 break
             }
+            last_comma_span = Some(self.prev_span);
+        }
+        if !bad_lifetime_pos.is_empty() {
+            let mut err = self.struct_span_err(
+                bad_lifetime_pos,
+                "lifetime parameters must be declared prior to type parameters",
+            );
+            if !suggestions.is_empty() {
+                err.multipart_suggestion_with_applicability(
+                    "move the lifetime parameter prior to the first type parameter",
+                    suggestions,
+                    Applicability::MachineApplicable,
+                );
+            }
+            err.emit();
         }
-        Ok(params)
+        lifetimes.extend(params);  // ensure the correct order of lifetimes and type params
+        Ok(lifetimes)
     }
 
     /// Parse a set of optional generic type parameter declarations. Where
diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs
index bb47d9b535bef..9fbc64758da4d 100644
--- a/src/libsyntax/ptr.rs
+++ b/src/libsyntax/ptr.rs
@@ -72,7 +72,7 @@ impl<T: 'static> P<T> {
         *self.ptr
     }
 
-    /// Transform the inner value, consuming `self` and producing a new `P<T>`.
+    /// Produce a new `P<T>` from `self` without reallocating.
     pub fn map<F>(mut self, f: F) -> P<T> where
         F: FnOnce(T) -> T,
     {
@@ -88,8 +88,30 @@ impl<T: 'static> P<T> {
             ptr::write(p, f(ptr::read(p)));
 
             // Recreate self from the raw pointer.
-            P {
-                ptr: Box::from_raw(p)
+            P { ptr: Box::from_raw(p) }
+        }
+    }
+
+    /// Optionally produce a new `P<T>` from `self` without reallocating.
+    pub fn filter_map<F>(mut self, f: F) -> Option<P<T>> where
+        F: FnOnce(T) -> Option<T>,
+    {
+        let p: *mut T = &mut *self.ptr;
+
+        // Leak self in case of panic.
+        // FIXME(eddyb) Use some sort of "free guard" that
+        // only deallocates, without dropping the pointee,
+        // in case the call the `f` below ends in a panic.
+        mem::forget(self);
+
+        unsafe {
+            if let Some(v) = f(ptr::read(p)) {
+                ptr::write(p, v);
+
+                // Recreate self from the raw pointer.
+                Some(P { ptr: Box::from_raw(p) })
+            } else {
+                None
             }
         }
     }
diff --git a/src/test/COMPILER_TESTS.md b/src/test/COMPILER_TESTS.md
index 81a46ea0fe718..c4ca478134399 100644
--- a/src/test/COMPILER_TESTS.md
+++ b/src/test/COMPILER_TESTS.md
@@ -1,4 +1,4 @@
 # Compiler Test Documentation
 
 Documentation the compiler testing framework has moved to
-[the rustc guide](https://rust-lang-nursery.github.io/rustc-guide/tests/intro.html).
+[the rustc guide](https://rust-lang.github.io/rustc-guide/tests/intro.html).
diff --git a/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs b/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs
index cec88f1c6a245..1793a311f968a 100644
--- a/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs
+++ b/src/test/codegen-units/item-collection/drop_in_place_intrinsic.rs
@@ -14,7 +14,7 @@
 
 #![feature(start)]
 
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<drop_in_place_intrinsic::StructWithDtor[0]> @@ drop_in_place_intrinsic-cgu.0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<drop_in_place_intrinsic::StructWithDtor[0]> @@ drop_in_place_intrinsic-cgu.0[Internal]
 struct StructWithDtor(u32);
 
 impl Drop for StructWithDtor {
@@ -26,7 +26,7 @@ impl Drop for StructWithDtor {
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]; 2]> @@ drop_in_place_intrinsic-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]; 2]> @@ drop_in_place_intrinsic-cgu.0[Internal]
     let x = [StructWithDtor(0), StructWithDtor(1)];
 
     drop_slice_in_place(&x);
@@ -41,6 +41,7 @@ fn drop_slice_in_place(x: &[StructWithDtor]) {
         // not have drop-glue for the unsized [StructWithDtor]. This has to be
         // generated though when the drop_in_place() intrinsic is used.
         //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]]> @@ drop_in_place_intrinsic-cgu.0[Internal]
+        //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<[drop_in_place_intrinsic::StructWithDtor[0]]> @@ drop_in_place_intrinsic-cgu.0[Internal]
         ::std::ptr::drop_in_place(x as *const _ as *mut [StructWithDtor]);
     }
 }
diff --git a/src/test/codegen-units/item-collection/generic-drop-glue.rs b/src/test/codegen-units/item-collection/generic-drop-glue.rs
index 5afa519bc5902..4ae5832ec4ed4 100644
--- a/src/test/codegen-units/item-collection/generic-drop-glue.rs
+++ b/src/test/codegen-units/item-collection/generic-drop-glue.rs
@@ -47,7 +47,7 @@ enum EnumNoDrop<T1, T2> {
 struct NonGenericNoDrop(i32);
 
 struct NonGenericWithDrop(i32);
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::NonGenericWithDrop[0]> @@ generic_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<generic_drop_glue::NonGenericWithDrop[0]> @@ generic_drop_glue-cgu.0[Internal]
 
 impl Drop for NonGenericWithDrop {
     //~ MONO_ITEM fn generic_drop_glue::{{impl}}[2]::drop[0]
@@ -57,11 +57,11 @@ impl Drop for NonGenericWithDrop {
 //~ MONO_ITEM fn generic_drop_glue::start[0]
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::StructWithDrop[0]<i8, char>> @@ generic_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<generic_drop_glue::StructWithDrop[0]<i8, char>> @@ generic_drop_glue-cgu.0[Internal]
     //~ MONO_ITEM fn generic_drop_glue::{{impl}}[0]::drop[0]<i8, char>
     let _ = StructWithDrop { x: 0i8, y: 'a' }.x;
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::StructWithDrop[0]<&str, generic_drop_glue::NonGenericNoDrop[0]>> @@ generic_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<generic_drop_glue::StructWithDrop[0]<&str, generic_drop_glue::NonGenericNoDrop[0]>> @@ generic_drop_glue-cgu.0[Internal]
     //~ MONO_ITEM fn generic_drop_glue::{{impl}}[0]::drop[0]<&str, generic_drop_glue::NonGenericNoDrop[0]>
     let _ = StructWithDrop { x: "&str", y: NonGenericNoDrop(0) }.y;
 
@@ -70,17 +70,17 @@ fn start(_: isize, _: *const *const u8) -> isize {
 
     // This is supposed to generate drop-glue because it contains a field that
     // needs to be dropped.
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::StructNoDrop[0]<generic_drop_glue::NonGenericWithDrop[0], f64>> @@ generic_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<generic_drop_glue::StructNoDrop[0]<generic_drop_glue::NonGenericWithDrop[0], f64>> @@ generic_drop_glue-cgu.0[Internal]
     let _ = StructNoDrop { x: NonGenericWithDrop(0), y: 0f64 }.y;
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::EnumWithDrop[0]<i32, i64>> @@ generic_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<generic_drop_glue::EnumWithDrop[0]<i32, i64>> @@ generic_drop_glue-cgu.0[Internal]
     //~ MONO_ITEM fn generic_drop_glue::{{impl}}[1]::drop[0]<i32, i64>
     let _ = match EnumWithDrop::A::<i32, i64>(0) {
         EnumWithDrop::A(x) => x,
         EnumWithDrop::B(x) => x as i32
     };
 
-    //~MONO_ITEM fn core::ptr[0]::drop_in_place[0]<generic_drop_glue::EnumWithDrop[0]<f64, f32>> @@ generic_drop_glue-cgu.0[Internal]
+    //~MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<generic_drop_glue::EnumWithDrop[0]<f64, f32>> @@ generic_drop_glue-cgu.0[Internal]
     //~ MONO_ITEM fn generic_drop_glue::{{impl}}[1]::drop[0]<f64, f32>
     let _ = match EnumWithDrop::B::<f64, f32>(1.0) {
         EnumWithDrop::A(x) => x,
diff --git a/src/test/codegen-units/item-collection/instantiation-through-vtable.rs b/src/test/codegen-units/item-collection/instantiation-through-vtable.rs
index d09d343a8458e..bfa67b16d0e63 100644
--- a/src/test/codegen-units/item-collection/instantiation-through-vtable.rs
+++ b/src/test/codegen-units/item-collection/instantiation-through-vtable.rs
@@ -34,13 +34,13 @@ impl<T> Trait for Struct<T> {
 fn start(_: isize, _: *const *const u8) -> isize {
     let s1 = Struct { _a: 0u32 };
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<instantiation_through_vtable::Struct[0]<u32>> @@ instantiation_through_vtable-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<instantiation_through_vtable::Struct[0]<u32>> @@ instantiation_through_vtable-cgu.0[Internal]
     //~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::foo[0]<u32>
     //~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::bar[0]<u32>
     let _ = &s1 as &Trait;
 
     let s1 = Struct { _a: 0u64 };
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<instantiation_through_vtable::Struct[0]<u64>> @@ instantiation_through_vtable-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<instantiation_through_vtable::Struct[0]<u64>> @@ instantiation_through_vtable-cgu.0[Internal]
     //~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::foo[0]<u64>
     //~ MONO_ITEM fn instantiation_through_vtable::{{impl}}[0]::bar[0]<u64>
     let _ = &s1 as &Trait;
diff --git a/src/test/codegen-units/item-collection/non-generic-drop-glue.rs b/src/test/codegen-units/item-collection/non-generic-drop-glue.rs
index a939dd56cda5b..2d72383391daa 100644
--- a/src/test/codegen-units/item-collection/non-generic-drop-glue.rs
+++ b/src/test/codegen-units/item-collection/non-generic-drop-glue.rs
@@ -15,7 +15,7 @@
 #![deny(dead_code)]
 #![feature(start)]
 
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<non_generic_drop_glue::StructWithDrop[0]> @@ non_generic_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<non_generic_drop_glue::StructWithDrop[0]> @@ non_generic_drop_glue-cgu.0[Internal]
 struct StructWithDrop {
     x: i32
 }
@@ -29,7 +29,7 @@ struct StructNoDrop {
     x: i32
 }
 
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<non_generic_drop_glue::EnumWithDrop[0]> @@ non_generic_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<non_generic_drop_glue::EnumWithDrop[0]> @@ non_generic_drop_glue-cgu.0[Internal]
 enum EnumWithDrop {
     A(i32)
 }
diff --git a/src/test/codegen-units/item-collection/transitive-drop-glue.rs b/src/test/codegen-units/item-collection/transitive-drop-glue.rs
index 7bbc9b6d0fbc9..d90171726b2c6 100644
--- a/src/test/codegen-units/item-collection/transitive-drop-glue.rs
+++ b/src/test/codegen-units/item-collection/transitive-drop-glue.rs
@@ -15,11 +15,11 @@
 #![deny(dead_code)]
 #![feature(start)]
 
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::Root[0]> @@ transitive_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::Root[0]> @@ transitive_drop_glue-cgu.0[Internal]
 struct Root(Intermediate);
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::Intermediate[0]> @@ transitive_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::Intermediate[0]> @@ transitive_drop_glue-cgu.0[Internal]
 struct Intermediate(Leaf);
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::Leaf[0]> @@ transitive_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::Leaf[0]> @@ transitive_drop_glue-cgu.0[Internal]
 struct Leaf;
 
 impl Drop for Leaf {
@@ -40,15 +40,15 @@ impl<T> Drop for LeafGen<T> {
 fn start(_: isize, _: *const *const u8) -> isize {
     let _ = Root(Intermediate(Leaf));
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::RootGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal]
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::IntermediateGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal]
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::LeafGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::RootGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::IntermediateGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::LeafGen[0]<u32>> @@ transitive_drop_glue-cgu.0[Internal]
     //~ MONO_ITEM fn transitive_drop_glue::{{impl}}[1]::drop[0]<u32>
     let _ = RootGen(IntermediateGen(LeafGen(0u32)));
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::RootGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal]
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::IntermediateGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal]
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<transitive_drop_glue::LeafGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::RootGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::IntermediateGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<transitive_drop_glue::LeafGen[0]<i16>> @@ transitive_drop_glue-cgu.0[Internal]
     //~ MONO_ITEM fn transitive_drop_glue::{{impl}}[1]::drop[0]<i16>
     let _ = RootGen(IntermediateGen(LeafGen(0i16)));
 
diff --git a/src/test/codegen-units/item-collection/tuple-drop-glue.rs b/src/test/codegen-units/item-collection/tuple-drop-glue.rs
index 865570ccfa55a..e94af0c2989b2 100644
--- a/src/test/codegen-units/item-collection/tuple-drop-glue.rs
+++ b/src/test/codegen-units/item-collection/tuple-drop-glue.rs
@@ -15,7 +15,7 @@
 #![deny(dead_code)]
 #![feature(start)]
 
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<tuple_drop_glue::Dropped[0]> @@ tuple_drop_glue-cgu.0[Internal]
+//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<tuple_drop_glue::Dropped[0]> @@ tuple_drop_glue-cgu.0[Internal]
 struct Dropped;
 
 impl Drop for Dropped {
@@ -26,11 +26,11 @@ impl Drop for Dropped {
 //~ MONO_ITEM fn tuple_drop_glue::start[0]
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(u32, tuple_drop_glue::Dropped[0])> @@ tuple_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<(u32, tuple_drop_glue::Dropped[0])> @@ tuple_drop_glue-cgu.0[Internal]
     let x = (0u32, Dropped);
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(i16, (tuple_drop_glue::Dropped[0], bool))> @@ tuple_drop_glue-cgu.0[Internal]
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(tuple_drop_glue::Dropped[0], bool)> @@ tuple_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<(i16, (tuple_drop_glue::Dropped[0], bool))> @@ tuple_drop_glue-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<(tuple_drop_glue::Dropped[0], bool)> @@ tuple_drop_glue-cgu.0[Internal]
     let x = (0i16, (Dropped, true));
 
     0
diff --git a/src/test/codegen-units/item-collection/unsizing.rs b/src/test/codegen-units/item-collection/unsizing.rs
index 5e9a3258c7adf..c85f7fc1bdd8d 100644
--- a/src/test/codegen-units/item-collection/unsizing.rs
+++ b/src/test/codegen-units/item-collection/unsizing.rs
@@ -59,13 +59,13 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Wrapper<U>> for Wrapper<T>
 fn start(_: isize, _: *const *const u8) -> isize {
     // simple case
     let bool_sized = &true;
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<bool> @@ unsizing-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<bool> @@ unsizing-cgu.0[Internal]
     //~ MONO_ITEM fn unsizing::{{impl}}[0]::foo[0]
     let _bool_unsized = bool_sized as &Trait;
 
     let char_sized = &'a';
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<char> @@ unsizing-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<char> @@ unsizing-cgu.0[Internal]
     //~ MONO_ITEM fn unsizing::{{impl}}[1]::foo[0]
     let _char_unsized = char_sized as &Trait;
 
@@ -75,13 +75,13 @@ fn start(_: isize, _: *const *const u8) -> isize {
         _b: 2,
         _c: 3.0f64
     };
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<f64> @@ unsizing-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<f64> @@ unsizing-cgu.0[Internal]
     //~ MONO_ITEM fn unsizing::{{impl}}[2]::foo[0]
     let _struct_unsized = struct_sized as &Struct<Trait>;
 
     // custom coercion
     let wrapper_sized = Wrapper(&0u32);
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<u32> @@ unsizing-cgu.0[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<u32> @@ unsizing-cgu.0[Internal]
     //~ MONO_ITEM fn unsizing::{{impl}}[3]::foo[0]
     let _wrapper_sized = wrapper_sized as Wrapper<Trait>;
 
diff --git a/src/test/codegen-units/partitioning/extern-drop-glue.rs b/src/test/codegen-units/partitioning/extern-drop-glue.rs
index cbad3a638840c..87b4430b4cab6 100644
--- a/src/test/codegen-units/partitioning/extern-drop-glue.rs
+++ b/src/test/codegen-units/partitioning/extern-drop-glue.rs
@@ -21,14 +21,14 @@
 // aux-build:cgu_extern_drop_glue.rs
 extern crate cgu_extern_drop_glue;
 
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<cgu_extern_drop_glue::Struct[0]> @@ extern_drop_glue[Internal] extern_drop_glue-mod1[Internal]
+//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<cgu_extern_drop_glue::Struct[0]> @@ extern_drop_glue[Internal] extern_drop_glue-mod1[Internal]
 
 struct LocalStruct(cgu_extern_drop_glue::Struct);
 
 //~ MONO_ITEM fn extern_drop_glue::user[0] @@ extern_drop_glue[External]
 pub fn user()
 {
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<extern_drop_glue::LocalStruct[0]> @@ extern_drop_glue[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<extern_drop_glue::LocalStruct[0]> @@ extern_drop_glue[Internal]
     let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
 }
 
@@ -40,7 +40,7 @@ pub mod mod1 {
     //~ MONO_ITEM fn extern_drop_glue::mod1[0]::user[0] @@ extern_drop_glue-mod1[External]
     pub fn user()
     {
-        //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<extern_drop_glue::mod1[0]::LocalStruct[0]> @@ extern_drop_glue-mod1[Internal]
+        //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<extern_drop_glue::mod1[0]::LocalStruct[0]> @@ extern_drop_glue-mod1[Internal]
         let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
     }
 }
diff --git a/src/test/codegen-units/partitioning/local-drop-glue.rs b/src/test/codegen-units/partitioning/local-drop-glue.rs
index 98729d99ea950..e09eb318708e1 100644
--- a/src/test/codegen-units/partitioning/local-drop-glue.rs
+++ b/src/test/codegen-units/partitioning/local-drop-glue.rs
@@ -17,7 +17,7 @@
 #![allow(dead_code)]
 #![crate_type="rlib"]
 
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::Struct[0]> @@ local_drop_glue[Internal] local_drop_glue-mod1[Internal]
+//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<local_drop_glue::Struct[0]> @@ local_drop_glue[Internal] local_drop_glue-mod1[Internal]
 struct Struct {
     _a: u32
 }
@@ -27,7 +27,7 @@ impl Drop for Struct {
     fn drop(&mut self) {}
 }
 
-//~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::Outer[0]> @@ local_drop_glue[Internal]
+//~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<local_drop_glue::Outer[0]> @@ local_drop_glue[Internal]
 struct Outer {
     _a: Struct
 }
@@ -46,10 +46,10 @@ pub mod mod1
 {
     use super::Struct;
 
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<local_drop_glue::mod1[0]::Struct2[0]> @@ local_drop_glue-mod1[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<local_drop_glue::mod1[0]::Struct2[0]> @@ local_drop_glue-mod1[Internal]
     struct Struct2 {
         _a: Struct,
-        //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<(u32, local_drop_glue::Struct[0])> @@ local_drop_glue-mod1[Internal]
+        //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<(u32, local_drop_glue::Struct[0])> @@ local_drop_glue-mod1[Internal]
         _b: (u32, Struct),
     }
 
diff --git a/src/test/codegen-units/partitioning/vtable-through-const.rs b/src/test/codegen-units/partitioning/vtable-through-const.rs
index ebda08a29f66d..459c6b6f15410 100644
--- a/src/test/codegen-units/partitioning/vtable-through-const.rs
+++ b/src/test/codegen-units/partitioning/vtable-through-const.rs
@@ -76,7 +76,7 @@ mod mod1 {
 //~ MONO_ITEM fn vtable_through_const::start[0]
 #[start]
 fn start(_: isize, _: *const *const u8) -> isize {
-    //~ MONO_ITEM fn core::ptr[0]::drop_in_place[0]<u32> @@ vtable_through_const[Internal]
+    //~ MONO_ITEM fn core::ptr[0]::real_drop_in_place[0]<u32> @@ vtable_through_const[Internal]
 
     // Since Trait1::do_something() is instantiated via its default implementation,
     // it is considered a generic and is instantiated here only because it is
diff --git a/src/test/codegen/issue-56267.rs b/src/test/codegen/issue-56267.rs
new file mode 100644
index 0000000000000..2c33f558931ed
--- /dev/null
+++ b/src/test/codegen/issue-56267.rs
@@ -0,0 +1,18 @@
+// compile-flags: -C no-prepopulate-passes
+
+#![crate_type="rlib"]
+
+#[allow(dead_code)]
+pub struct Foo<T> {
+    foo: u64,
+    bar: T,
+}
+
+// The store writing to bar.1 should have alignment 4. Not checking
+// other stores here, as the alignment will be platform-dependent.
+
+// CHECK: store i32 [[TMP1:%.+]], i32* [[TMP2:%.+]], align 4
+#[no_mangle]
+pub fn test(x: (i32, i32)) -> Foo<(i32, i32)> {
+    Foo { foo: 0, bar: x }
+}
diff --git a/src/test/compile-fail-fulldeps/auxiliary/lint_for_crate.rs b/src/test/compile-fail-fulldeps/auxiliary/lint_for_crate.rs
index 460e28fc794f0..fc53031e7f226 100644
--- a/src/test/compile-fail-fulldeps/auxiliary/lint_for_crate.rs
+++ b/src/test/compile-fail-fulldeps/auxiliary/lint_for_crate.rs
@@ -12,7 +12,6 @@
 
 #![feature(plugin_registrar, rustc_private)]
 #![feature(box_syntax)]
-#![feature(macro_at_most_once_rep)]
 
 #[macro_use] extern crate rustc;
 extern crate rustc_plugin;
diff --git a/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs b/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs
index 1057649d969d1..f697642f8431d 100644
--- a/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs
+++ b/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs
@@ -12,7 +12,6 @@
 
 #![feature(plugin_registrar)]
 #![feature(box_syntax, rustc_private)]
-#![feature(macro_at_most_once_rep)]
 
 // Load rustc as a plugin to get macros
 #[macro_use]
diff --git a/src/test/compile-fail-fulldeps/auxiliary/lint_plugin_test.rs b/src/test/compile-fail-fulldeps/auxiliary/lint_plugin_test.rs
index b0183a3c56bc4..8647797270f9a 100644
--- a/src/test/compile-fail-fulldeps/auxiliary/lint_plugin_test.rs
+++ b/src/test/compile-fail-fulldeps/auxiliary/lint_plugin_test.rs
@@ -12,7 +12,6 @@
 
 #![feature(plugin_registrar)]
 #![feature(box_syntax, rustc_private)]
-#![feature(macro_at_most_once_rep)]
 
 extern crate syntax;
 
diff --git a/src/test/run-make/llvm-outputs/Makefile b/src/test/run-make/llvm-outputs/Makefile
new file mode 100644
index 0000000000000..d7f67577b04ce
--- /dev/null
+++ b/src/test/run-make/llvm-outputs/Makefile
@@ -0,0 +1,5 @@
+-include ../../run-make-fulldeps/tools.mk
+
+all:
+	echo 'fn main() {}' | $(BARE_RUSTC) - --out-dir=$(TMPDIR)/random_directory_that_does_not_exist_ir/ --emit=llvm-ir
+	echo 'fn main() {}' | $(BARE_RUSTC) - --out-dir=$(TMPDIR)/random_directory_that_does_not_exist_bc/ --emit=llvm-bc
diff --git a/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs b/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs
index 00c419a8d09e8..9f6927d21640e 100644
--- a/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs
@@ -12,7 +12,6 @@
 
 #![feature(plugin_registrar, rustc_private)]
 #![feature(box_syntax)]
-#![feature(macro_at_most_once_rep)]
 
 #[macro_use] extern crate rustc;
 extern crate rustc_plugin;
diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-40001-plugin.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-40001-plugin.rs
index e0acf340a79fd..f4d3f2c94caf1 100644
--- a/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-40001-plugin.rs
+++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/issue-40001-plugin.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 #![feature(box_syntax, plugin, plugin_registrar, rustc_private)]
-#![feature(macro_at_most_once_rep)]
 #![crate_type = "dylib"]
 
 #[macro_use]
diff --git a/src/test/run-pass/binding/fn-arg-incomplete-pattern-drop-order.rs b/src/test/run-pass/binding/fn-arg-incomplete-pattern-drop-order.rs
new file mode 100644
index 0000000000000..41e0750000146
--- /dev/null
+++ b/src/test/run-pass/binding/fn-arg-incomplete-pattern-drop-order.rs
@@ -0,0 +1,54 @@
+// Check that partially moved from function parameters are dropped after the
+// named bindings that move from them.
+
+use std::{panic, cell::RefCell};
+
+struct LogDrop<'a>(i32, Context<'a>);
+
+#[derive(Copy, Clone)]
+struct Context<'a> {
+    panic_on: i32,
+    drops: &'a RefCell<Vec<i32>>,
+}
+
+impl<'a> Context<'a> {
+    fn record_drop(self, index: i32) {
+        self.drops.borrow_mut().push(index);
+        if index == self.panic_on {
+            panic!();
+        }
+    }
+}
+
+impl<'a> Drop for LogDrop<'a> {
+    fn drop(&mut self) {
+        self.1.record_drop(self.0);
+    }
+}
+
+fn foo((_x, _): (LogDrop, LogDrop), (_, _y): (LogDrop, LogDrop)) {}
+
+fn test_drop_order(panic_on: i32) {
+    let context = Context {
+        panic_on,
+        drops: &RefCell::new(Vec::new()),
+    };
+    let one = LogDrop(1, context);
+    let two = LogDrop(2, context);
+    let three = LogDrop(3, context);
+    let four = LogDrop(4, context);
+
+    let res = panic::catch_unwind(panic::AssertUnwindSafe(|| {
+        foo((three, four), (two, one));
+    }));
+    if panic_on == 0 {
+        assert!(res.is_ok(), "should not have panicked");
+    } else {
+        assert!(res.is_err(), "should have panicked");
+    }
+    assert_eq!(*context.drops.borrow(), [1, 2, 3, 4], "incorrect drop order");
+}
+
+fn main() {
+    (0..=4).for_each(test_drop_order);
+}
diff --git a/src/test/run-pass/macros/macro-at-most-once-rep.rs b/src/test/run-pass/macros/macro-at-most-once-rep.rs
index c7129423cb651..563fd01c11147 100644
--- a/src/test/run-pass/macros/macro-at-most-once-rep.rs
+++ b/src/test/run-pass/macros/macro-at-most-once-rep.rs
@@ -22,8 +22,6 @@
 
 // edition:2018
 
-#![feature(macro_at_most_once_rep)]
-
 macro_rules! foo {
     ($($a:ident)? ; $num:expr) => { {
         let mut x = 0;
diff --git a/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs
index 1057649d969d1..f697642f8431d 100644
--- a/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs
+++ b/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs
@@ -12,7 +12,6 @@
 
 #![feature(plugin_registrar)]
 #![feature(box_syntax, rustc_private)]
-#![feature(macro_at_most_once_rep)]
 
 // Load rustc as a plugin to get macros
 #[macro_use]
diff --git a/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs
index b0183a3c56bc4..8647797270f9a 100644
--- a/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs
+++ b/src/test/ui-fulldeps/auxiliary/lint_plugin_test.rs
@@ -12,7 +12,6 @@
 
 #![feature(plugin_registrar)]
 #![feature(box_syntax, rustc_private)]
-#![feature(macro_at_most_once_rep)]
 
 extern crate syntax;
 
diff --git a/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs b/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs
index 7d2acd7aa4c86..0a449e338bd06 100644
--- a/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs
+++ b/src/test/ui-fulldeps/auxiliary/lint_tool_test.rs
@@ -10,7 +10,6 @@
 
 #![feature(plugin_registrar)]
 #![feature(box_syntax, rustc_private)]
-#![feature(macro_at_most_once_rep)]
 
 extern crate syntax;
 
diff --git a/src/test/ui/did_you_mean/recursion_limit_deref.stderr b/src/test/ui/did_you_mean/recursion_limit_deref.stderr
index 20a94f7aac196..7e7f21dd69c92 100644
--- a/src/test/ui/did_you_mean/recursion_limit_deref.stderr
+++ b/src/test/ui/did_you_mean/recursion_limit_deref.stderr
@@ -1,4 +1,4 @@
-error[E0055]: reached the recursion limit while auto-dereferencing I
+error[E0055]: reached the recursion limit while auto-dereferencing `I`
   --> $DIR/recursion_limit_deref.rs:60:22
    |
 LL |     let x: &Bottom = &t; //~ ERROR mismatched types
diff --git a/src/test/ui/error-codes/E0004-2.stderr b/src/test/ui/error-codes/E0004-2.stderr
index 900812787bcf7..2d46196ddda55 100644
--- a/src/test/ui/error-codes/E0004-2.stderr
+++ b/src/test/ui/error-codes/E0004-2.stderr
@@ -1,4 +1,4 @@
-error[E0004]: non-exhaustive patterns: type std::option::Option<i32> is non-empty
+error[E0004]: non-exhaustive patterns: type `std::option::Option<i32>` is non-empty
   --> $DIR/E0004-2.rs:14:11
    |
 LL |     match x { } //~ ERROR E0004
diff --git a/src/test/ui/error-codes/E0055.stderr b/src/test/ui/error-codes/E0055.stderr
index 9653f4eaeefd0..dddbd92765a5d 100644
--- a/src/test/ui/error-codes/E0055.stderr
+++ b/src/test/ui/error-codes/E0055.stderr
@@ -1,4 +1,4 @@
-error[E0055]: reached the recursion limit while auto-dereferencing Foo
+error[E0055]: reached the recursion limit while auto-dereferencing `Foo`
   --> $DIR/E0055.rs:21:13
    |
 LL |     ref_foo.foo();
diff --git a/src/test/ui/infinite/infinite-autoderef.stderr b/src/test/ui/infinite/infinite-autoderef.stderr
index b5e20ea5cbf99..ef68adecd1a5f 100644
--- a/src/test/ui/infinite/infinite-autoderef.stderr
+++ b/src/test/ui/infinite/infinite-autoderef.stderr
@@ -7,7 +7,7 @@ LL |         x = box x;
    |             cyclic type of infinite size
    |             help: try using a conversion method: `box x.to_string()`
 
-error[E0055]: reached the recursion limit while auto-dereferencing Foo
+error[E0055]: reached the recursion limit while auto-dereferencing `Foo`
   --> $DIR/infinite-autoderef.rs:35:5
    |
 LL |     Foo.foo;
@@ -15,7 +15,7 @@ LL |     Foo.foo;
    |
    = help: consider adding a `#![recursion_limit="128"]` attribute to your crate
 
-error[E0055]: reached the recursion limit while auto-dereferencing Foo
+error[E0055]: reached the recursion limit while auto-dereferencing `Foo`
   --> $DIR/infinite-autoderef.rs:35:9
    |
 LL |     Foo.foo;
@@ -29,7 +29,7 @@ error[E0609]: no field `foo` on type `Foo`
 LL |     Foo.foo;
    |         ^^^ unknown field
 
-error[E0055]: reached the recursion limit while auto-dereferencing Foo
+error[E0055]: reached the recursion limit while auto-dereferencing `Foo`
   --> $DIR/infinite-autoderef.rs:36:9
    |
 LL |     Foo.bar();
diff --git a/src/test/ui/issues/issue-3096-1.stderr b/src/test/ui/issues/issue-3096-1.stderr
index b2bfe6b5e8c07..f0782bd973805 100644
--- a/src/test/ui/issues/issue-3096-1.stderr
+++ b/src/test/ui/issues/issue-3096-1.stderr
@@ -1,4 +1,4 @@
-error[E0004]: non-exhaustive patterns: type () is non-empty
+error[E0004]: non-exhaustive patterns: type `()` is non-empty
   --> $DIR/issue-3096-1.rs:12:11
    |
 LL |     match () { } //~ ERROR non-exhaustive
diff --git a/src/test/ui/issues/issue-3096-2.stderr b/src/test/ui/issues/issue-3096-2.stderr
index bb9dfabe7be03..e0fa641ff39e7 100644
--- a/src/test/ui/issues/issue-3096-2.stderr
+++ b/src/test/ui/issues/issue-3096-2.stderr
@@ -1,4 +1,4 @@
-error[E0004]: non-exhaustive patterns: type *const bottom is non-empty
+error[E0004]: non-exhaustive patterns: type `*const bottom` is non-empty
   --> $DIR/issue-3096-2.rs:15:11
    |
 LL |     match x { } //~ ERROR non-exhaustive patterns
diff --git a/src/test/ui/issues/issue-38940.rs b/src/test/ui/issues/issue-38940.rs
index 7f9b141e02e3c..1c785949547e5 100644
--- a/src/test/ui/issues/issue-38940.rs
+++ b/src/test/ui/issues/issue-38940.rs
@@ -42,5 +42,5 @@ fn main() {
     let t = Top::new();
     let x: &Bottom = &t;
     //~^ ERROR mismatched types
-    //~| ERROR reached the recursion limit while auto-dereferencing I
+    //~| ERROR reached the recursion limit while auto-dereferencing `I`
 }
diff --git a/src/test/ui/issues/issue-38940.stderr b/src/test/ui/issues/issue-38940.stderr
index 2d3cfda9a5f72..d94a7101c0a38 100644
--- a/src/test/ui/issues/issue-38940.stderr
+++ b/src/test/ui/issues/issue-38940.stderr
@@ -1,4 +1,4 @@
-error[E0055]: reached the recursion limit while auto-dereferencing I
+error[E0055]: reached the recursion limit while auto-dereferencing `I`
   --> $DIR/issue-38940.rs:43:22
    |
 LL |     let x: &Bottom = &t;
diff --git a/src/test/ui/issues/issue-56202.rs b/src/test/ui/issues/issue-56202.rs
new file mode 100644
index 0000000000000..c80c372c9e2ea
--- /dev/null
+++ b/src/test/ui/issues/issue-56202.rs
@@ -0,0 +1,15 @@
+#![feature(self_struct_ctor)]
+
+trait FooTrait {}
+
+trait BarTrait {
+    fn foo<T: FooTrait>(_: T) -> Self;
+}
+
+struct FooStruct(u32);
+
+impl BarTrait for FooStruct {
+    fn foo<T: FooTrait>(_: T) -> Self {
+        Self(u32::default())
+    }
+}
diff --git a/src/test/ui/issues/issue-56202.stderr b/src/test/ui/issues/issue-56202.stderr
new file mode 100644
index 0000000000000..3007b08450298
--- /dev/null
+++ b/src/test/ui/issues/issue-56202.stderr
@@ -0,0 +1,7 @@
+error[E0601]: `main` function not found in crate `issue_56202`
+   |
+   = note: consider adding a `main` function to `$DIR/issue-56202.rs`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.rs b/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.rs
deleted file mode 100644
index 63a4ef16a2581..0000000000000
--- a/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.rs
+++ /dev/null
@@ -1,28 +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.
-
-// Test behavior of `?` macro _kleene op_ under the 2015 edition. Namely, it doesn't exist, even
-// with the feature flag.
-
-// gate-test-macro_at_most_once_rep
-// edition:2015
-
-#![feature(macro_at_most_once_rep)]
-
-macro_rules! bar {
-    ($(a)?) => {} //~ERROR expected `*` or `+`
-}
-
-macro_rules! baz {
-    ($(a),?) => {} //~ERROR expected `*` or `+`
-}
-
-fn main() {}
-
diff --git a/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.stderr b/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.stderr
deleted file mode 100644
index 5f687900421bf..0000000000000
--- a/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.stderr
+++ /dev/null
@@ -1,18 +0,0 @@
-error: expected `*` or `+`
-  --> $DIR/macro-at-most-once-rep-2015-ques-rep-feature-flag.rs:20:10
-   |
-LL |     ($(a)?) => {} //~ERROR expected `*` or `+`
-   |          ^
-   |
-   = note: `?` is not a macro repetition operator
-
-error: expected `*` or `+`
-  --> $DIR/macro-at-most-once-rep-2015-ques-rep-feature-flag.rs:24:11
-   |
-LL |     ($(a),?) => {} //~ERROR expected `*` or `+`
-   |           ^
-   |
-   = note: `?` is not a macro repetition operator
-
-error: aborting due to 2 previous errors
-
diff --git a/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.rs b/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.rs
deleted file mode 100644
index ffabf9bcdf685..0000000000000
--- a/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.rs
+++ /dev/null
@@ -1,45 +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.
-
-// Feature gate test for macro_at_most_once_rep under 2018 edition.
-
-// gate-test-macro_at_most_once_rep
-// edition:2018
-
-macro_rules! foo {
-    ($(a)?) => {}
-    //~^ERROR using the `?` macro Kleene operator for
-    //~|ERROR expected `*` or `+`
-}
-
-macro_rules! baz {
-    ($(a),?) => {} //~ERROR expected `*` or `+`
-}
-
-macro_rules! barplus {
-    ($(a)?+) => {}
-    //~^ERROR using the `?` macro Kleene operator for
-    //~|ERROR expected `*` or `+`
-}
-
-macro_rules! barstar {
-    ($(a)?*) => {}
-    //~^ERROR using the `?` macro Kleene operator for
-    //~|ERROR expected `*` or `+`
-}
-
-pub fn main() {
-    foo!();
-    foo!(a);
-    foo!(a?); //~ ERROR no rules expected the token `?`
-    foo!(a?a); //~ ERROR no rules expected the token `?`
-    foo!(a?a?a); //~ ERROR no rules expected the token `?`
-}
-
diff --git a/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.stderr b/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.stderr
deleted file mode 100644
index 27dc03e1c3981..0000000000000
--- a/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.stderr
+++ /dev/null
@@ -1,80 +0,0 @@
-error[E0658]: using the `?` macro Kleene operator for "at most one" repetition is unstable (see issue #48075)
-  --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:17:10
-   |
-LL |     ($(a)?) => {}
-   |          ^
-   |
-   = help: add #![feature(macro_at_most_once_rep)] to the crate attributes to enable
-
-error: expected `*` or `+`
-  --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:17:10
-   |
-LL |     ($(a)?) => {}
-   |          ^
-
-error: expected `*` or `+`
-  --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:23:11
-   |
-LL |     ($(a),?) => {} //~ERROR expected `*` or `+`
-   |           ^
-   |
-   = note: `?` is not a macro repetition operator
-
-error[E0658]: using the `?` macro Kleene operator for "at most one" repetition is unstable (see issue #48075)
-  --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:27:10
-   |
-LL |     ($(a)?+) => {}
-   |          ^
-   |
-   = help: add #![feature(macro_at_most_once_rep)] to the crate attributes to enable
-
-error: expected `*` or `+`
-  --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:27:10
-   |
-LL |     ($(a)?+) => {}
-   |          ^
-
-error[E0658]: using the `?` macro Kleene operator for "at most one" repetition is unstable (see issue #48075)
-  --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:33:10
-   |
-LL |     ($(a)?*) => {}
-   |          ^
-   |
-   = help: add #![feature(macro_at_most_once_rep)] to the crate attributes to enable
-
-error: expected `*` or `+`
-  --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:33:10
-   |
-LL |     ($(a)?*) => {}
-   |          ^
-
-error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:41:11
-   |
-LL | macro_rules! foo {
-   | ---------------- when calling this macro
-...
-LL |     foo!(a?); //~ ERROR no rules expected the token `?`
-   |           ^ no rules expected this token in macro call
-
-error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:42:11
-   |
-LL | macro_rules! foo {
-   | ---------------- when calling this macro
-...
-LL |     foo!(a?a); //~ ERROR no rules expected the token `?`
-   |           ^ no rules expected this token in macro call
-
-error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:43:11
-   |
-LL | macro_rules! foo {
-   | ---------------- when calling this macro
-...
-LL |     foo!(a?a?a); //~ ERROR no rules expected the token `?`
-   |           ^ no rules expected this token in macro call
-
-error: aborting due to 10 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/macros/macro-at-most-once-rep-2018.rs b/src/test/ui/macros/macro-at-most-once-rep-2018.rs
index 5dabe8d952801..78bdf8ff71b88 100644
--- a/src/test/ui/macros/macro-at-most-once-rep-2018.rs
+++ b/src/test/ui/macros/macro-at-most-once-rep-2018.rs
@@ -12,22 +12,20 @@
 
 // edition:2018
 
-#![feature(macro_at_most_once_rep)]
-
 macro_rules! foo {
-    ($(a)?) => {}
+    ($(a)?) => {};
 }
 
 macro_rules! baz {
-    ($(a),?) => {} //~ERROR the `?` macro repetition operator
+    ($(a),?) => {}; //~ERROR the `?` macro repetition operator
 }
 
 macro_rules! barplus {
-    ($(a)?+) => {} // ok. matches "a+" and "+"
+    ($(a)?+) => {}; // ok. matches "a+" and "+"
 }
 
 macro_rules! barstar {
-    ($(a)?*) => {} // ok. matches "a*" and "*"
+    ($(a)?*) => {}; // ok. matches "a*" and "*"
 }
 
 pub fn main() {
diff --git a/src/test/ui/macros/macro-at-most-once-rep-2018.stderr b/src/test/ui/macros/macro-at-most-once-rep-2018.stderr
index d363b672680ee..da76d1ff1a721 100644
--- a/src/test/ui/macros/macro-at-most-once-rep-2018.stderr
+++ b/src/test/ui/macros/macro-at-most-once-rep-2018.stderr
@@ -1,11 +1,11 @@
 error: the `?` macro repetition operator does not take a separator
-  --> $DIR/macro-at-most-once-rep-2018.rs:22:10
+  --> $DIR/macro-at-most-once-rep-2018.rs:20:10
    |
-LL |     ($(a),?) => {} //~ERROR the `?` macro repetition operator
+LL |     ($(a),?) => {}; //~ERROR the `?` macro repetition operator
    |          ^
 
 error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-2018.rs:36:11
+  --> $DIR/macro-at-most-once-rep-2018.rs:34:11
    |
 LL | macro_rules! foo {
    | ---------------- when calling this macro
@@ -14,7 +14,7 @@ LL |     foo!(a?); //~ ERROR no rules expected the token `?`
    |           ^ no rules expected this token in macro call
 
 error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-2018.rs:37:11
+  --> $DIR/macro-at-most-once-rep-2018.rs:35:11
    |
 LL | macro_rules! foo {
    | ---------------- when calling this macro
@@ -23,7 +23,7 @@ LL |     foo!(a?a); //~ ERROR no rules expected the token `?`
    |           ^ no rules expected this token in macro call
 
 error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-2018.rs:38:11
+  --> $DIR/macro-at-most-once-rep-2018.rs:36:11
    |
 LL | macro_rules! foo {
    | ---------------- when calling this macro
@@ -32,7 +32,7 @@ LL |     foo!(a?a?a); //~ ERROR no rules expected the token `?`
    |           ^ no rules expected this token in macro call
 
 error: unexpected end of macro invocation
-  --> $DIR/macro-at-most-once-rep-2018.rs:40:5
+  --> $DIR/macro-at-most-once-rep-2018.rs:38:5
    |
 LL | macro_rules! barplus {
    | -------------------- when calling this macro
@@ -41,7 +41,7 @@ LL |     barplus!(); //~ERROR unexpected end of macro invocation
    |     ^^^^^^^^^^^ missing tokens in macro arguments
 
 error: unexpected end of macro invocation
-  --> $DIR/macro-at-most-once-rep-2018.rs:41:15
+  --> $DIR/macro-at-most-once-rep-2018.rs:39:15
    |
 LL | macro_rules! barplus {
    | -------------------- when calling this macro
@@ -50,7 +50,7 @@ LL |     barplus!(a); //~ERROR unexpected end of macro invocation
    |               ^ missing tokens in macro arguments
 
 error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-2018.rs:42:15
+  --> $DIR/macro-at-most-once-rep-2018.rs:40:15
    |
 LL | macro_rules! barplus {
    | -------------------- when calling this macro
@@ -59,7 +59,7 @@ LL |     barplus!(a?); //~ ERROR no rules expected the token `?`
    |               ^ no rules expected this token in macro call
 
 error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-2018.rs:43:15
+  --> $DIR/macro-at-most-once-rep-2018.rs:41:15
    |
 LL | macro_rules! barplus {
    | -------------------- when calling this macro
@@ -68,7 +68,7 @@ LL |     barplus!(a?a); //~ ERROR no rules expected the token `?`
    |               ^ no rules expected this token in macro call
 
 error: unexpected end of macro invocation
-  --> $DIR/macro-at-most-once-rep-2018.rs:47:5
+  --> $DIR/macro-at-most-once-rep-2018.rs:45:5
    |
 LL | macro_rules! barstar {
    | -------------------- when calling this macro
@@ -77,7 +77,7 @@ LL |     barstar!(); //~ERROR unexpected end of macro invocation
    |     ^^^^^^^^^^^ missing tokens in macro arguments
 
 error: unexpected end of macro invocation
-  --> $DIR/macro-at-most-once-rep-2018.rs:48:15
+  --> $DIR/macro-at-most-once-rep-2018.rs:46:15
    |
 LL | macro_rules! barstar {
    | -------------------- when calling this macro
@@ -86,7 +86,7 @@ LL |     barstar!(a); //~ERROR unexpected end of macro invocation
    |               ^ missing tokens in macro arguments
 
 error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-2018.rs:49:15
+  --> $DIR/macro-at-most-once-rep-2018.rs:47:15
    |
 LL | macro_rules! barstar {
    | -------------------- when calling this macro
@@ -95,7 +95,7 @@ LL |     barstar!(a?); //~ ERROR no rules expected the token `?`
    |               ^ no rules expected this token in macro call
 
 error: no rules expected the token `?`
-  --> $DIR/macro-at-most-once-rep-2018.rs:50:15
+  --> $DIR/macro-at-most-once-rep-2018.rs:48:15
    |
 LL | macro_rules! barstar {
    | -------------------- when calling this macro
diff --git a/src/test/ui/parser/issue-14303-enum.stderr b/src/test/ui/parser/issue-14303-enum.stderr
index 7d546cb2180e3..622066a94f80a 100644
--- a/src/test/ui/parser/issue-14303-enum.stderr
+++ b/src/test/ui/parser/issue-14303-enum.stderr
@@ -3,6 +3,10 @@ error: lifetime parameters must be declared prior to type parameters
    |
 LL | enum X<'a, T, 'b> {
    |               ^^
+help: move the lifetime parameter prior to the first type parameter
+   |
+LL | enum X<'a, 'b, T> {
+   |            ^^^ --
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-14303-fn-def.stderr b/src/test/ui/parser/issue-14303-fn-def.stderr
index c7b57f36376b5..630c9cb40de37 100644
--- a/src/test/ui/parser/issue-14303-fn-def.stderr
+++ b/src/test/ui/parser/issue-14303-fn-def.stderr
@@ -3,6 +3,10 @@ error: lifetime parameters must be declared prior to type parameters
    |
 LL | fn foo<'a, T, 'b>(x: &'a T) {}
    |               ^^
+help: move the lifetime parameter prior to the first type parameter
+   |
+LL | fn foo<'a, 'b, T>(x: &'a T) {}
+   |            ^^^ --
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-14303-impl.stderr b/src/test/ui/parser/issue-14303-impl.stderr
index 0b7016eb7f71d..2e3181de90275 100644
--- a/src/test/ui/parser/issue-14303-impl.stderr
+++ b/src/test/ui/parser/issue-14303-impl.stderr
@@ -3,6 +3,10 @@ error: lifetime parameters must be declared prior to type parameters
    |
 LL | impl<'a, T, 'b> X {}
    |             ^^
+help: move the lifetime parameter prior to the first type parameter
+   |
+LL | impl<'a, 'b, T> X {}
+   |          ^^^ --
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-14303-struct.stderr b/src/test/ui/parser/issue-14303-struct.stderr
index 4a4b678919495..c6b33120c18f0 100644
--- a/src/test/ui/parser/issue-14303-struct.stderr
+++ b/src/test/ui/parser/issue-14303-struct.stderr
@@ -3,6 +3,10 @@ error: lifetime parameters must be declared prior to type parameters
    |
 LL | struct X<'a, T, 'b> {
    |                 ^^
+help: move the lifetime parameter prior to the first type parameter
+   |
+LL | struct X<'a, 'b, T> {
+   |              ^^^ --
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-14303-trait.stderr b/src/test/ui/parser/issue-14303-trait.stderr
index ab5cc5655bbe1..6d00f284bbbe7 100644
--- a/src/test/ui/parser/issue-14303-trait.stderr
+++ b/src/test/ui/parser/issue-14303-trait.stderr
@@ -3,6 +3,10 @@ error: lifetime parameters must be declared prior to type parameters
    |
 LL | trait Foo<'a, T, 'b> {}
    |                  ^^
+help: move the lifetime parameter prior to the first type parameter
+   |
+LL | trait Foo<'a, 'b, T> {}
+   |               ^^^ --
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/suggest-move-lifetimes.rs b/src/test/ui/suggestions/suggest-move-lifetimes.rs
new file mode 100644
index 0000000000000..5051a406078aa
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-move-lifetimes.rs
@@ -0,0 +1,21 @@
+struct A<T, 'a> {
+    t: &'a T,
+}
+
+struct B<T, 'a, U> {
+    t: &'a T,
+    u: U,
+}
+
+struct C<T, U, 'a> {
+    t: &'a T,
+    u: U,
+}
+
+struct D<T, U, 'a, 'b, V, 'c> {
+    t: &'a T,
+    u: &'b U,
+    v: &'c V,
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/suggest-move-lifetimes.stderr b/src/test/ui/suggestions/suggest-move-lifetimes.stderr
new file mode 100644
index 0000000000000..f3d6469b51255
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-move-lifetimes.stderr
@@ -0,0 +1,42 @@
+error: lifetime parameters must be declared prior to type parameters
+  --> $DIR/suggest-move-lifetimes.rs:1:13
+   |
+LL | struct A<T, 'a> {
+   |             ^^
+help: move the lifetime parameter prior to the first type parameter
+   |
+LL | struct A<'a, T> {
+   |          ^^^ --
+
+error: lifetime parameters must be declared prior to type parameters
+  --> $DIR/suggest-move-lifetimes.rs:5:13
+   |
+LL | struct B<T, 'a, U> {
+   |             ^^
+help: move the lifetime parameter prior to the first type parameter
+   |
+LL | struct B<'a, T, U> {
+   |          ^^^   --
+
+error: lifetime parameters must be declared prior to type parameters
+  --> $DIR/suggest-move-lifetimes.rs:10:16
+   |
+LL | struct C<T, U, 'a> {
+   |                ^^
+help: move the lifetime parameter prior to the first type parameter
+   |
+LL | struct C<'a, T, U> {
+   |          ^^^    --
+
+error: lifetime parameters must be declared prior to type parameters
+  --> $DIR/suggest-move-lifetimes.rs:15:16
+   |
+LL | struct D<T, U, 'a, 'b, V, 'c> {
+   |                ^^  ^^     ^^
+help: move the lifetime parameter prior to the first type parameter
+   |
+LL | struct D<'a, 'b, 'c, T, U, V> {
+   |          ^^^ ^^^ ^^^      ---
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr
index 83fd736a997a9..f4974b8fa3854 100644
--- a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr
+++ b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr
@@ -4,7 +4,7 @@ error[E0004]: non-exhaustive patterns: `Err(_)` not covered
 LL |     let _ = match x {   //~ ERROR non-exhaustive
    |                   ^ pattern `Err(_)` not covered
 
-error[E0004]: non-exhaustive patterns: type &Void is non-empty
+error[E0004]: non-exhaustive patterns: type `&Void` is non-empty
   --> $DIR/uninhabited-matches-feature-gated.rs:20:19
    |
 LL |     let _ = match x {}; //~ ERROR non-exhaustive
@@ -16,7 +16,7 @@ help: ensure that all possible cases are being handled, possibly by adding wildc
 LL |     let _ = match x {}; //~ ERROR non-exhaustive
    |                   ^
 
-error[E0004]: non-exhaustive patterns: type (Void,) is non-empty
+error[E0004]: non-exhaustive patterns: type `(Void,)` is non-empty
   --> $DIR/uninhabited-matches-feature-gated.rs:23:19
    |
 LL |     let _ = match x {}; //~ ERROR non-exhaustive
@@ -28,7 +28,7 @@ help: ensure that all possible cases are being handled, possibly by adding wildc
 LL |     let _ = match x {}; //~ ERROR non-exhaustive
    |                   ^
 
-error[E0004]: non-exhaustive patterns: type [Void; 1] is non-empty
+error[E0004]: non-exhaustive patterns: type `[Void; 1]` is non-empty
   --> $DIR/uninhabited-matches-feature-gated.rs:26:19
    |
 LL |     let _ = match x {}; //~ ERROR non-exhaustive
diff --git a/src/stage0.txt b/stage0.txt
similarity index 100%
rename from src/stage0.txt
rename to stage0.txt