From 5a7cd848f740291f94f2400b50f41136fc8657bb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= <bsteinbr@gmail.com>
Date: Mon, 21 Jan 2019 19:36:27 +0100
Subject: [PATCH 01/24] Speed up the fast path for assert_eq! and assert_ne!

Currently, the panic!() calls directly borrow the value bindings. This
causes those bindings to always be initialized, i.e. they're initialized
even before the values are even compared. This causes noticeable
overhead in what should be a really cheap operation.

By performing a reborrow of the value in the call to panic!(), we allow
LLVM to optimize that code, so that the extra borrow only happens in the
error case.

We could achieve the same result by dereferencing the values passed to
panic!(), as the format machinery borrows them anyway, but this causes
assertions to fail to compile if one of the values is unsized, i.e. it
would be a breaking change.
---
 src/libcore/macros.rs | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index 2f350df2f5c18..5eaefb7d1cc51 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -45,9 +45,12 @@ macro_rules! assert_eq {
         match (&$left, &$right) {
             (left_val, right_val) => {
                 if !(*left_val == *right_val) {
+                    // The reborrows below are intentional. Without them, the stack slot for the
+                    // borrow is initialized even before the values are compared, leading to a
+                    // noticeable slow down.
                     panic!(r#"assertion failed: `(left == right)`
   left: `{:?}`,
- right: `{:?}`"#, left_val, right_val)
+ right: `{:?}`"#, &*left_val, &*right_val)
                 }
             }
         }
@@ -59,9 +62,12 @@ macro_rules! assert_eq {
         match (&($left), &($right)) {
             (left_val, right_val) => {
                 if !(*left_val == *right_val) {
+                    // The reborrows below are intentional. Without them, the stack slot for the
+                    // borrow is initialized even before the values are compared, leading to a
+                    // noticeable slow down.
                     panic!(r#"assertion failed: `(left == right)`
   left: `{:?}`,
- right: `{:?}`: {}"#, left_val, right_val,
+ right: `{:?}`: {}"#, &*left_val, &*right_val,
                            format_args!($($arg)+))
                 }
             }
@@ -96,9 +102,12 @@ macro_rules! assert_ne {
         match (&$left, &$right) {
             (left_val, right_val) => {
                 if *left_val == *right_val {
+                    // The reborrows below are intentional. Without them, the stack slot for the
+                    // borrow is initialized even before the values are compared, leading to a
+                    // noticeable slow down.
                     panic!(r#"assertion failed: `(left != right)`
   left: `{:?}`,
- right: `{:?}`"#, left_val, right_val)
+ right: `{:?}`"#, &*left_val, &*right_val)
                 }
             }
         }
@@ -110,9 +119,12 @@ macro_rules! assert_ne {
         match (&($left), &($right)) {
             (left_val, right_val) => {
                 if *left_val == *right_val {
+                    // The reborrows below are intentional. Without them, the stack slot for the
+                    // borrow is initialized even before the values are compared, leading to a
+                    // noticeable slow down.
                     panic!(r#"assertion failed: `(left != right)`
   left: `{:?}`,
- right: `{:?}`: {}"#, left_val, right_val,
+ right: `{:?}`: {}"#, &*left_val, &*right_val,
                            format_args!($($arg)+))
                 }
             }

From f841ff4a7b8227f17e0fa056c6a73ba549f2872e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= <faern@faern.net>
Date: Thu, 31 Jan 2019 20:46:11 +0100
Subject: [PATCH 02/24] Stabilize the time_checked_add feature

---
 src/libstd/time.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index 23924559fcc24..6685ee202658a 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -245,7 +245,7 @@ impl Instant {
     /// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be represented as
     /// `Instant` (which means it's inside the bounds of the underlying data structure), `None`
     /// otherwise.
-    #[unstable(feature = "time_checked_add", issue = "55940")]
+    #[stable(feature = "time_checked_add", since = "1.34.0")]
     pub fn checked_add(&self, duration: Duration) -> Option<Instant> {
         self.0.checked_add_duration(&duration).map(|t| Instant(t))
     }
@@ -253,7 +253,7 @@ impl Instant {
     /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as
     /// `Instant` (which means it's inside the bounds of the underlying data structure), `None`
     /// otherwise.
-    #[unstable(feature = "time_checked_add", issue = "55940")]
+    #[stable(feature = "time_checked_add", since = "1.34.0")]
     pub fn checked_sub(&self, duration: Duration) -> Option<Instant> {
         self.0.checked_sub_duration(&duration).map(|t| Instant(t))
     }
@@ -418,7 +418,7 @@ impl SystemTime {
     /// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be represented as
     /// `SystemTime` (which means it's inside the bounds of the underlying data structure), `None`
     /// otherwise.
-    #[unstable(feature = "time_checked_add", issue = "55940")]
+    #[stable(feature = "time_checked_add", since = "1.34.0")]
     pub fn checked_add(&self, duration: Duration) -> Option<SystemTime> {
         self.0.checked_add_duration(&duration).map(|t| SystemTime(t))
     }
@@ -426,7 +426,7 @@ impl SystemTime {
     /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as
     /// `SystemTime` (which means it's inside the bounds of the underlying data structure), `None`
     /// otherwise.
-    #[unstable(feature = "time_checked_add", issue = "55940")]
+    #[stable(feature = "time_checked_add", since = "1.34.0")]
     pub fn checked_sub(&self, duration: Duration) -> Option<SystemTime> {
         self.0.checked_sub_duration(&duration).map(|t| SystemTime(t))
     }

From 2f2d49523a8a2cd4e3156dc2f810a83ef37e1872 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= <faern@faern.net>
Date: Thu, 31 Jan 2019 23:18:07 +0100
Subject: [PATCH 03/24] Simplify lambdas

---
 src/libstd/time.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index 6685ee202658a..b63d816ce44ca 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -247,7 +247,7 @@ impl Instant {
     /// otherwise.
     #[stable(feature = "time_checked_add", since = "1.34.0")]
     pub fn checked_add(&self, duration: Duration) -> Option<Instant> {
-        self.0.checked_add_duration(&duration).map(|t| Instant(t))
+        self.0.checked_add_duration(&duration).map(Instant)
     }
 
     /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as
@@ -255,7 +255,7 @@ impl Instant {
     /// otherwise.
     #[stable(feature = "time_checked_add", since = "1.34.0")]
     pub fn checked_sub(&self, duration: Duration) -> Option<Instant> {
-        self.0.checked_sub_duration(&duration).map(|t| Instant(t))
+        self.0.checked_sub_duration(&duration).map(Instant)
     }
 }
 
@@ -420,7 +420,7 @@ impl SystemTime {
     /// otherwise.
     #[stable(feature = "time_checked_add", since = "1.34.0")]
     pub fn checked_add(&self, duration: Duration) -> Option<SystemTime> {
-        self.0.checked_add_duration(&duration).map(|t| SystemTime(t))
+        self.0.checked_add_duration(&duration).map(SystemTime)
     }
 
     /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as
@@ -428,7 +428,7 @@ impl SystemTime {
     /// otherwise.
     #[stable(feature = "time_checked_add", since = "1.34.0")]
     pub fn checked_sub(&self, duration: Duration) -> Option<SystemTime> {
-        self.0.checked_sub_duration(&duration).map(|t| SystemTime(t))
+        self.0.checked_sub_duration(&duration).map(SystemTime)
     }
 }
 

From 6d8566995444b80b9ea4f0eaa9ad4daa0c1f5db2 Mon Sep 17 00:00:00 2001
From: MikaelUrankar <mikael.urankar@gmail.com>
Date: Sat, 2 Feb 2019 16:41:38 +0100
Subject: [PATCH 04/24] Add FreeBSD armv6 and armv7 targets

---
 src/bootstrap/bootstrap.py                    |  4 ++++
 .../spec/armv6_unknown_freebsd.rs             | 24 +++++++++++++++++++
 .../spec/armv7_unknown_freebsd.rs             | 24 +++++++++++++++++++
 src/librustc_target/spec/mod.rs               |  2 ++
 4 files changed, 54 insertions(+)
 create mode 100644 src/librustc_target/spec/armv6_unknown_freebsd.rs
 create mode 100644 src/librustc_target/spec/armv7_unknown_freebsd.rs

diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 119b38bcc99dc..7813d9bd63c02 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -262,6 +262,10 @@ def default_build_triple():
         cputype = 'arm'
         if ostype == 'linux-android':
             ostype = 'linux-androideabi'
+        elif ostype == 'unknown-freebsd':
+            cputype = subprocess.check_output(
+                ['uname', '-p']).strip().decode(default_encoding)
+            ostype = 'unknown-freebsd'
     elif cputype == 'armv6l':
         cputype = 'arm'
         if ostype == 'linux-android':
diff --git a/src/librustc_target/spec/armv6_unknown_freebsd.rs b/src/librustc_target/spec/armv6_unknown_freebsd.rs
new file mode 100644
index 0000000000000..ada9b3212593b
--- /dev/null
+++ b/src/librustc_target/spec/armv6_unknown_freebsd.rs
@@ -0,0 +1,24 @@
+use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+    let base = super::freebsd_base::opts();
+    Ok(Target {
+        llvm_target: "armv6-unknown-freebsd-gnueabihf".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "32".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
+        arch: "arm".to_string(),
+        target_os: "freebsd".to_string(),
+        target_env: "gnueabihf".to_string(),
+        target_vendor: "unknown".to_string(),
+        linker_flavor: LinkerFlavor::Gcc,
+
+        options: TargetOptions {
+            features: "+v6,+vfp2".to_string(),
+            max_atomic_width: Some(64),
+            abi_blacklist: super::arm_base::abi_blacklist(),
+            .. base
+        }
+    })
+}
diff --git a/src/librustc_target/spec/armv7_unknown_freebsd.rs b/src/librustc_target/spec/armv7_unknown_freebsd.rs
new file mode 100644
index 0000000000000..e4f6a07ee3062
--- /dev/null
+++ b/src/librustc_target/spec/armv7_unknown_freebsd.rs
@@ -0,0 +1,24 @@
+use spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+    let base = super::freebsd_base::opts();
+    Ok(Target {
+        llvm_target: "armv7-unknown-freebsd-gnueabihf".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "32".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
+        arch: "arm".to_string(),
+        target_os: "freebsd".to_string(),
+        target_env: "gnueabihf".to_string(),
+        target_vendor: "unknown".to_string(),
+        linker_flavor: LinkerFlavor::Gcc,
+
+        options: TargetOptions {
+            features: "+v7,+vfp3,+d16,+thumb2,-neon".to_string(),
+            max_atomic_width: Some(64),
+            abi_blacklist: super::arm_base::abi_blacklist(),
+            .. base
+        }
+    })
+}
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index e47da3cff95b6..5c40aaaa6b070 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -366,6 +366,8 @@ supported_targets! {
     ("aarch64-linux-android", aarch64_linux_android),
 
     ("aarch64-unknown-freebsd", aarch64_unknown_freebsd),
+    ("armv6-unknown-freebsd", armv6_unknown_freebsd),
+    ("armv7-unknown-freebsd", armv7_unknown_freebsd),
     ("i686-unknown-freebsd", i686_unknown_freebsd),
     ("powerpc64-unknown-freebsd", powerpc64_unknown_freebsd),
     ("x86_64-unknown-freebsd", x86_64_unknown_freebsd),

From 346dc37aee60f995e6c1548ce7f406d5500f8570 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 5 Feb 2019 20:07:45 +0100
Subject: [PATCH 05/24] fix str mutating through a ptr derived from &self

---
 src/libcore/str/mod.rs | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 3cb3936038093..b01cb688ee5c6 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -1757,7 +1757,7 @@ mod traits {
         }
         #[inline]
         unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
-            let ptr = slice.as_ptr().add(self.start);
+            let ptr = slice.as_mut_ptr().add(self.start);
             let len = self.end - self.start;
             super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr as *mut u8, len))
         }
@@ -1821,7 +1821,7 @@ mod traits {
         }
         #[inline]
         unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
-            let ptr = slice.as_ptr();
+            let ptr = slice.as_mut_ptr();
             super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr as *mut u8, self.end))
         }
         #[inline]
@@ -1883,7 +1883,7 @@ mod traits {
         }
         #[inline]
         unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
-            let ptr = slice.as_ptr().add(self.start);
+            let ptr = slice.as_mut_ptr().add(self.start);
             let len = slice.len() - self.start;
             super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr as *mut u8, len))
         }
@@ -2213,6 +2213,22 @@ impl str {
         self as *const str as *const u8
     }
 
+    /// Converts a mutable string slice to a raw pointer.
+    ///
+    /// As string slices are a slice of bytes, the raw pointer points to a
+    /// [`u8`]. This pointer will be pointing to the first byte of the string
+    /// slice.
+    ///
+    /// It is your responsibility to make sure that the string slice only gets
+    /// modified in a way that it remains valid UTF-8.
+    ///
+    /// [`u8`]: primitive.u8.html
+    #[unstable(feature = "str_as_mut_ptr", issue = "0")]
+    #[inline]
+    pub fn as_mut_ptr(&mut self) -> *mut u8 {
+        self as *mut str as *mut u8
+    }
+
     /// Returns a subslice of `str`.
     ///
     /// This is the non-panicking alternative to indexing the `str`. Returns

From 113b7f7be15c49fcd0854ca53486e92f1badfdd6 Mon Sep 17 00:00:00 2001
From: Andy Russell <arussell123@gmail.com>
Date: Mon, 4 Feb 2019 12:41:01 -0500
Subject: [PATCH 06/24] allow shorthand syntax for deprecation reason

---
 src/libsyntax/attr/builtin.rs                 | 125 +++++++++---------
 src/libsyntax/attr/mod.rs                     |   4 +
 src/libsyntax/feature_gate.rs                 |  12 +-
 src/test/rustdoc/deprecated.rs                |   5 +
 src/test/ui/deprecation/deprecation-sanity.rs |   6 +
 .../ui/deprecation/deprecation-sanity.stderr  |  20 ++-
 src/test/ui/deprecation/invalid-literal.rs    |   4 +
 .../ui/deprecation/invalid-literal.stderr     |   8 ++
 8 files changed, 117 insertions(+), 67 deletions(-)
 create mode 100644 src/test/ui/deprecation/invalid-literal.rs
 create mode 100644 src/test/ui/deprecation/invalid-literal.stderr

diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs
index 08c7c617a7bef..7230a2922c420 100644
--- a/src/libsyntax/attr/builtin.rs
+++ b/src/libsyntax/attr/builtin.rs
@@ -592,81 +592,86 @@ fn find_deprecation_generic<'a, I>(sess: &ParseSess,
     let diagnostic = &sess.span_diagnostic;
 
     'outer: for attr in attrs_iter {
-        if attr.path != "deprecated" {
-            continue
+        if !attr.check_name("deprecated") {
+            continue;
         }
 
-        mark_used(attr);
-
         if depr.is_some() {
             span_err!(diagnostic, item_sp, E0550, "multiple deprecated attributes");
             break
         }
 
-        depr = if let Some(metas) = attr.meta_item_list() {
-            let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
-                if item.is_some() {
-                    handle_errors(sess, meta.span, AttrError::MultipleItem(meta.name()));
-                    return false
-                }
-                if let Some(v) = meta.value_str() {
-                    *item = Some(v);
-                    true
-                } else {
-                    if let Some(lit) = meta.name_value_literal() {
-                        handle_errors(
-                            sess,
-                            lit.span,
-                            AttrError::UnsupportedLiteral(
-                                "literal in `deprecated` \
-                                value must be a string",
-                                lit.node.is_bytestr()
-                            ),
-                        );
-                    } else {
-                        span_err!(diagnostic, meta.span, E0551, "incorrect meta item");
+        let meta = attr.meta().unwrap();
+        depr = match &meta.node {
+            MetaItemKind::Word => Some(Deprecation { since: None, note: None }),
+            MetaItemKind::NameValue(..) => {
+                meta.value_str().map(|note| {
+                    Deprecation { since: None, note: Some(note) }
+                })
+            }
+            MetaItemKind::List(list) => {
+                let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
+                    if item.is_some() {
+                        handle_errors(sess, meta.span, AttrError::MultipleItem(meta.name()));
+                        return false
                     }
+                    if let Some(v) = meta.value_str() {
+                        *item = Some(v);
+                        true
+                    } else {
+                        if let Some(lit) = meta.name_value_literal() {
+                            handle_errors(
+                                sess,
+                                lit.span,
+                                AttrError::UnsupportedLiteral(
+                                    "literal in `deprecated` \
+                                    value must be a string",
+                                    lit.node.is_bytestr()
+                                ),
+                            );
+                        } else {
+                            span_err!(diagnostic, meta.span, E0551, "incorrect meta item");
+                        }
 
-                    false
-                }
-            };
+                        false
+                    }
+                };
 
-            let mut since = None;
-            let mut note = None;
-            for meta in metas {
-                match &meta.node {
-                    NestedMetaItemKind::MetaItem(mi) => {
-                        match &*mi.name().as_str() {
-                            "since" => if !get(mi, &mut since) { continue 'outer },
-                            "note" => if !get(mi, &mut note) { continue 'outer },
-                            _ => {
-                                handle_errors(
-                                    sess,
-                                    meta.span,
-                                    AttrError::UnknownMetaItem(mi.name(), &["since", "note"]),
-                                );
-                                continue 'outer
+                let mut since = None;
+                let mut note = None;
+                for meta in list {
+                    match &meta.node {
+                        NestedMetaItemKind::MetaItem(mi) => {
+                            match &*mi.name().as_str() {
+                                "since" => if !get(mi, &mut since) { continue 'outer },
+                                "note" => if !get(mi, &mut note) { continue 'outer },
+                                _ => {
+                                    handle_errors(
+                                        sess,
+                                        meta.span,
+                                        AttrError::UnknownMetaItem(mi.name(), &["since", "note"]),
+                                    );
+                                    continue 'outer
+                                }
                             }
                         }
-                    }
-                    NestedMetaItemKind::Literal(lit) => {
-                        handle_errors(
-                            sess,
-                            lit.span,
-                            AttrError::UnsupportedLiteral(
-                                "item in `deprecated` must be a key/value pair",
-                                false,
-                            ),
-                        );
-                        continue 'outer
+                        NestedMetaItemKind::Literal(lit) => {
+                            handle_errors(
+                                sess,
+                                lit.span,
+                                AttrError::UnsupportedLiteral(
+                                    "item in `deprecated` must be a key/value pair",
+                                    false,
+                                ),
+                            );
+                            continue 'outer
+                        }
                     }
                 }
-            }
 
-            Some(Deprecation {since: since, note: note})
-        } else {
-            Some(Deprecation{since: None, note: None})
-        }
+                Some(Deprecation { since, note })
+            }
+        };
     }
 
     depr
diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs
index 58be7c3e085c3..7e0342e1cba55 100644
--- a/src/libsyntax/attr/mod.rs
+++ b/src/libsyntax/attr/mod.rs
@@ -161,6 +161,10 @@ fn name_from_path(path: &Path) -> Name {
 }
 
 impl Attribute {
+    /// Returns `true` if the attribute's path matches the argument. If it matches, then the
+    /// attribute is marked as used.
+    ///
+    /// To check the attribute name without marking it used, use the `path` field directly.
     pub fn check_name(&self, name: &str) -> bool {
         let matches = self.path == name;
         if matches {
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 9dd17b420aa44..9a63a2c678b88 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -1176,9 +1176,15 @@ pub const BUILTIN_ATTRIBUTES: &[(&str, AttributeType, AttributeTemplate, Attribu
     ("stable", Whitelisted, template!(List: r#"feature = "name", since = "version""#), Ungated),
     ("unstable", Whitelisted, template!(List: r#"feature = "name", reason = "...", issue = "N""#),
                                         Ungated),
-    ("deprecated", Normal, template!(Word, List: r#"/*opt*/ since = "version",
-                                                    /*opt*/ note = "reason"#,
-                                                    NameValueStr: "reason"), Ungated),
+    ("deprecated",
+        Normal,
+        template!(
+            Word,
+            List: r#"/*opt*/ since = "version", /*opt*/ note = "reason"#,
+            NameValueStr: "reason"
+        ),
+        Ungated
+    ),
 
     ("rustc_paren_sugar", Normal, template!(Word), Gated(Stability::Unstable,
                                         "unboxed_closures",
diff --git a/src/test/rustdoc/deprecated.rs b/src/test/rustdoc/deprecated.rs
index ca3f380ed2825..ecb74719d74cc 100644
--- a/src/test/rustdoc/deprecated.rs
+++ b/src/test/rustdoc/deprecated.rs
@@ -26,3 +26,8 @@ pub struct V;
 //      'Deprecated$'
 #[deprecated]
 pub struct W;
+
+// @matches deprecated/struct.X.html '//*[@class="stab deprecated"]' \
+//      'Deprecated: shorthand reason$'
+#[deprecated = "shorthand reason"]
+pub struct X;
diff --git a/src/test/ui/deprecation/deprecation-sanity.rs b/src/test/ui/deprecation/deprecation-sanity.rs
index 09bae0bdfb13e..a559908b792bb 100644
--- a/src/test/ui/deprecation/deprecation-sanity.rs
+++ b/src/test/ui/deprecation/deprecation-sanity.rs
@@ -15,6 +15,12 @@ mod bogus_attribute_types_1 {
 
     #[deprecated(since(b), note = "a")] //~ ERROR incorrect meta item
     fn f6() { }
+
+    #[deprecated(note = b"test")] //~ ERROR literal in `deprecated` value must be a string
+    fn f7() { }
+
+    #[deprecated("test")] //~ ERROR item in `deprecated` must be a key/value pair
+    fn f8() { }
 }
 
 #[deprecated(since = "a", note = "b")]
diff --git a/src/test/ui/deprecation/deprecation-sanity.stderr b/src/test/ui/deprecation/deprecation-sanity.stderr
index a8bfcc23cc8cc..a071a4fc10d51 100644
--- a/src/test/ui/deprecation/deprecation-sanity.stderr
+++ b/src/test/ui/deprecation/deprecation-sanity.stderr
@@ -28,19 +28,31 @@ error[E0551]: incorrect meta item
 LL |     #[deprecated(since(b), note = "a")] //~ ERROR incorrect meta item
    |                  ^^^^^^^^
 
+error[E0565]: literal in `deprecated` value must be a string
+  --> $DIR/deprecation-sanity.rs:19:25
+   |
+LL |     #[deprecated(note = b"test")] //~ ERROR literal in `deprecated` value must be a string
+   |                         ^^^^^^^ help: consider removing the prefix: `"test"`
+
+error[E0565]: item in `deprecated` must be a key/value pair
+  --> $DIR/deprecation-sanity.rs:22:18
+   |
+LL |     #[deprecated("test")] //~ ERROR item in `deprecated` must be a key/value pair
+   |                  ^^^^^^
+
 error[E0550]: multiple deprecated attributes
-  --> $DIR/deprecation-sanity.rs:22:1
+  --> $DIR/deprecation-sanity.rs:28:1
    |
 LL | fn multiple1() { } //~ ERROR multiple deprecated attributes
    | ^^^^^^^^^^^^^^^^^^
 
 error[E0538]: multiple 'since' items
-  --> $DIR/deprecation-sanity.rs:24:27
+  --> $DIR/deprecation-sanity.rs:30:27
    |
 LL | #[deprecated(since = "a", since = "b", note = "c")] //~ ERROR multiple 'since' items
    |                           ^^^^^^^^^^^
 
-error: aborting due to 7 previous errors
+error: aborting due to 9 previous errors
 
-Some errors occurred: E0538, E0541, E0550, E0551.
+Some errors occurred: E0538, E0541, E0550, E0551, E0565.
 For more information about an error, try `rustc --explain E0538`.
diff --git a/src/test/ui/deprecation/invalid-literal.rs b/src/test/ui/deprecation/invalid-literal.rs
new file mode 100644
index 0000000000000..7e0d8cdfc2f72
--- /dev/null
+++ b/src/test/ui/deprecation/invalid-literal.rs
@@ -0,0 +1,4 @@
+#[deprecated = b"test"] //~ ERROR attribute must be of the form
+fn foo() {}
+
+fn main() {}
diff --git a/src/test/ui/deprecation/invalid-literal.stderr b/src/test/ui/deprecation/invalid-literal.stderr
new file mode 100644
index 0000000000000..f13d599c0b137
--- /dev/null
+++ b/src/test/ui/deprecation/invalid-literal.stderr
@@ -0,0 +1,8 @@
+error: attribute must be of the form `#[deprecated]` or `#[deprecated(/*opt*/ since = "version", /*opt*/ note = "reason)]` or `#[deprecated = "reason"]`
+  --> $DIR/invalid-literal.rs:1:1
+   |
+LL | #[deprecated = b"test"] //~ ERROR attribute must be of the form
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+

From 703540de4c878d829168bb6752a5154c33873f22 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Tue, 5 Feb 2019 21:27:26 +0100
Subject: [PATCH 07/24] Add specific error for unstable const fn features

---
 src/librustc_mir/diagnostics.rs              | 31 ++++++++++++++++++++
 src/librustc_mir/transform/qualify_consts.rs | 12 +++++++-
 2 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/src/librustc_mir/diagnostics.rs b/src/librustc_mir/diagnostics.rs
index eb72175421638..0858c0de3be41 100644
--- a/src/librustc_mir/diagnostics.rs
+++ b/src/librustc_mir/diagnostics.rs
@@ -2370,6 +2370,37 @@ let value = (&foo(), &foo());
 ```
 "##,
 
+E0723: r##"
+An feature unstable in `const` contexts was used.
+
+Erroneous code example:
+
+```compile_fail,E0723
+trait T {}
+
+impl T for () {}
+
+const fn foo() -> impl T { // error: `impl Trait` in const fn is unstable
+    ()
+}
+```
+
+To enable this feature on a nightly version of rustc, add the `const_fn`
+feature flag:
+
+```compile_fail,E0723
+#![feature(const_fn)]
+
+trait T {}
+
+impl T for () {}
+
+const fn foo() -> impl T { // error: `impl Trait` in const fn is unstable
+    ()
+}
+```
+"##,
+
 }
 
 register_diagnostics! {
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 2d941902debc3..f41564bd1fbd6 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -1179,7 +1179,17 @@ impl MirPass for QualifyAndPromoteConstants {
                         // enforce `min_const_fn` for stable const fns
                         use super::qualify_min_const_fn::is_min_const_fn;
                         if let Err((span, err)) = is_min_const_fn(tcx, def_id, mir) {
-                            tcx.sess.span_err(span, &err);
+                            let mut diag = struct_span_err!(
+                                tcx.sess,
+                                span,
+                                E0723,
+                                "{} (see issue #57563)",
+                                err,
+                            );
+                            diag.help(
+                                "add #![feature(const_fn)] to the crate attributes to enable",
+                            );
+                            diag.emit();
                         } else {
                             // this should not produce any errors, but better safe than sorry
                             // FIXME(#53819)

From 5a16a25977989b4c3a12d4936f7d8f7134162197 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Tue, 5 Feb 2019 21:27:44 +0100
Subject: [PATCH 08/24] Update const fn tests

---
 .../min_const_fn/bad_const_fn_body_ice.stderr |   4 +-
 .../ui/consts/min_const_fn/cast_errors.stderr |  21 ++-
 .../min_const_fn/cmp_fn_pointers.stderr       |   5 +-
 .../ui/consts/min_const_fn/loop_ice.stderr    |   5 +-
 .../consts/min_const_fn/min_const_fn.stderr   | 135 +++++++++++++-----
 .../min_const_fn/min_const_fn_dyn.stderr      |   9 +-
 .../min_const_fn/min_const_fn_fn_ptr.stderr   |   9 +-
 .../min_const_fn_libstd_stability.stderr      |  17 ++-
 ...in_const_unsafe_fn_libstd_stability.stderr |  17 ++-
 ...n_const_unsafe_fn_libstd_stability2.stderr |  13 +-
 .../consts/min_const_fn/mutable_borrow.stderr |   9 +-
 .../ui/consts/single_variant_match_ice.stderr |   7 +-
 src/test/ui/issues/issue-37550.stderr         |   5 +-
 src/test/ui/unsafe/ranged_ints2_const.stderr  |  11 +-
 14 files changed, 202 insertions(+), 65 deletions(-)

diff --git a/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr b/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr
index f6b704370b6f2..62f678790d21f 100644
--- a/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr
+++ b/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr
@@ -1,10 +1,12 @@
-error: heap allocations are not allowed in const fn
+error[E0723]: heap allocations are not allowed in const fn (see issue #57563)
   --> $DIR/bad_const_fn_body_ice.rs:2:5
    |
 LL |     vec![1, 2, 3] //~ ERROR heap allocations are not allowed in const fn
    |     ^^^^^^^^^^^^^
    |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0723`.
diff --git a/src/test/ui/consts/min_const_fn/cast_errors.stderr b/src/test/ui/consts/min_const_fn/cast_errors.stderr
index ba980b7aacb6c..b5af3e7ee4665 100644
--- a/src/test/ui/consts/min_const_fn/cast_errors.stderr
+++ b/src/test/ui/consts/min_const_fn/cast_errors.stderr
@@ -1,32 +1,43 @@
-error: unsizing casts are not allowed in const fn
+error[E0723]: unsizing casts are not allowed in const fn (see issue #57563)
   --> $DIR/cast_errors.rs:3:41
    |
 LL | const fn unsize(x: &[u8; 3]) -> &[u8] { x }
    |                                         ^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: function pointers in const fn are unstable
+error[E0723]: function pointers in const fn are unstable (see issue #57563)
   --> $DIR/cast_errors.rs:5:23
    |
 LL | const fn closure() -> fn() { || {} }
    |                       ^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: function pointers in const fn are unstable
+error[E0723]: function pointers in const fn are unstable (see issue #57563)
   --> $DIR/cast_errors.rs:8:5
    |
 LL |     (|| {}) as fn();
    |     ^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: function pointers in const fn are unstable
+error[E0723]: function pointers in const fn are unstable (see issue #57563)
   --> $DIR/cast_errors.rs:11:28
    |
 LL | const fn reify(f: fn()) -> unsafe fn() { f }
    |                            ^^^^^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: function pointers in const fn are unstable
+error[E0723]: function pointers in const fn are unstable (see issue #57563)
   --> $DIR/cast_errors.rs:13:21
    |
 LL | const fn reify2() { main as unsafe fn(); }
    |                     ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
 error: aborting due to 5 previous errors
 
+For more information about this error, try `rustc --explain E0723`.
diff --git a/src/test/ui/consts/min_const_fn/cmp_fn_pointers.stderr b/src/test/ui/consts/min_const_fn/cmp_fn_pointers.stderr
index a050c10e02cf9..d84e2651d4fc4 100644
--- a/src/test/ui/consts/min_const_fn/cmp_fn_pointers.stderr
+++ b/src/test/ui/consts/min_const_fn/cmp_fn_pointers.stderr
@@ -1,8 +1,11 @@
-error: function pointers in const fn are unstable
+error[E0723]: function pointers in const fn are unstable (see issue #57563)
   --> $DIR/cmp_fn_pointers.rs:1:14
    |
 LL | const fn cmp(x: fn(), y: fn()) -> bool { //~ ERROR function pointers in const fn are unstable
    |              ^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0723`.
diff --git a/src/test/ui/consts/min_const_fn/loop_ice.stderr b/src/test/ui/consts/min_const_fn/loop_ice.stderr
index 1424cea65afd5..716e8380c45da 100644
--- a/src/test/ui/consts/min_const_fn/loop_ice.stderr
+++ b/src/test/ui/consts/min_const_fn/loop_ice.stderr
@@ -1,8 +1,11 @@
-error: loops are not allowed in const fn
+error[E0723]: loops are not allowed in const fn (see issue #57563)
   --> $DIR/loop_ice.rs:2:5
    |
 LL |     loop {} //~ ERROR loops are not allowed in const fn
    |     ^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0723`.
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.stderr
index 52c60c57b8fb3..e095ccaf20e29 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_fn.stderr
@@ -4,11 +4,13 @@ error[E0493]: destructors cannot be evaluated at compile-time
 LL |     const fn into_inner(self) -> T { self.0 } //~ destructors cannot be evaluated
    |                         ^^^^ constant functions cannot evaluate destructors
 
-error: mutable references in const fn are unstable
+error[E0723]: mutable references in const fn are unstable (see issue #57563)
   --> $DIR/min_const_fn.rs:39:36
    |
 LL |     const fn get_mut(&mut self) -> &mut T { &mut self.0 }
    |                                    ^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
 error[E0493]: destructors cannot be evaluated at compile-time
   --> $DIR/min_const_fn.rs:44:28
@@ -16,11 +18,13 @@ error[E0493]: destructors cannot be evaluated at compile-time
 LL |     const fn into_inner_lt(self) -> T { self.0 } //~ destructors cannot be evaluated
    |                            ^^^^ constant functions cannot evaluate destructors
 
-error: mutable references in const fn are unstable
+error[E0723]: mutable references in const fn are unstable (see issue #57563)
   --> $DIR/min_const_fn.rs:46:42
    |
 LL |     const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 }
    |                                          ^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
 error[E0493]: destructors cannot be evaluated at compile-time
   --> $DIR/min_const_fn.rs:51:27
@@ -28,192 +32,255 @@ error[E0493]: destructors cannot be evaluated at compile-time
 LL |     const fn into_inner_s(self) -> T { self.0 } //~ ERROR destructors
    |                           ^^^^ constant functions cannot evaluate destructors
 
-error: mutable references in const fn are unstable
+error[E0723]: mutable references in const fn are unstable (see issue #57563)
   --> $DIR/min_const_fn.rs:53:38
    |
 LL |     const fn get_mut_s(&mut self) -> &mut T { &mut self.0 }
    |                                      ^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: mutable references in const fn are unstable
+error[E0723]: mutable references in const fn are unstable (see issue #57563)
   --> $DIR/min_const_fn.rs:58:39
    |
 LL |     const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 }
    |                                       ^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: trait bounds other than `Sized` on const fn parameters are unstable
+error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable (see issue #57563)
   --> $DIR/min_const_fn.rs:76:16
    |
 LL | const fn foo11<T: std::fmt::Display>(t: T) -> T { t }
    |                ^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: trait bounds other than `Sized` on const fn parameters are unstable
+error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable (see issue #57563)
   --> $DIR/min_const_fn.rs:78:18
    |
 LL | const fn foo11_2<T: Send>(t: T) -> T { t }
    |                  ^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: only int, `bool` and `char` operations are stable in const fn
+error[E0723]: only int, `bool` and `char` operations are stable in const fn (see issue #57563)
   --> $DIR/min_const_fn.rs:80:33
    |
 LL | const fn foo19(f: f32) -> f32 { f * 2.0 }
    |                                 ^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: only int, `bool` and `char` operations are stable in const fn
+error[E0723]: only int, `bool` and `char` operations are stable in const fn (see issue #57563)
   --> $DIR/min_const_fn.rs:82:35
    |
 LL | const fn foo19_2(f: f32) -> f32 { 2.0 - f }
    |                                   ^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: only int and `bool` operations are stable in const fn
+error[E0723]: only int and `bool` operations are stable in const fn (see issue #57563)
   --> $DIR/min_const_fn.rs:84:35
    |
 LL | const fn foo19_3(f: f32) -> f32 { -f }
    |                                   ^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: only int, `bool` and `char` operations are stable in const fn
+error[E0723]: only int, `bool` and `char` operations are stable in const fn (see issue #57563)
   --> $DIR/min_const_fn.rs:86:43
    |
 LL | const fn foo19_4(f: f32, g: f32) -> f32 { f / g }
    |                                           ^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: cannot access `static` items in const fn
+error[E0723]: cannot access `static` items in const fn (see issue #57563)
   --> $DIR/min_const_fn.rs:90:27
    |
 LL | const fn foo25() -> u32 { BAR } //~ ERROR cannot access `static` items in const fn
    |                           ^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: cannot access `static` items in const fn
+error[E0723]: cannot access `static` items in const fn (see issue #57563)
   --> $DIR/min_const_fn.rs:91:36
    |
 LL | const fn foo26() -> &'static u32 { &BAR } //~ ERROR cannot access `static` items
    |                                    ^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: casting pointers to ints is unstable in const fn
+error[E0723]: casting pointers to ints is unstable in const fn (see issue #57563)
   --> $DIR/min_const_fn.rs:92:42
    |
 LL | const fn foo30(x: *const u32) -> usize { x as usize }
    |                                          ^^^^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: casting pointers to ints is unstable in const fn
+error[E0723]: casting pointers to ints is unstable in const fn (see issue #57563)
   --> $DIR/min_const_fn.rs:94:63
    |
 LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } }
    |                                                               ^^^^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: casting pointers to ints is unstable in const fn
+error[E0723]: casting pointers to ints is unstable in const fn (see issue #57563)
   --> $DIR/min_const_fn.rs:96:42
    |
 LL | const fn foo30_2(x: *mut u32) -> usize { x as usize }
    |                                          ^^^^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: casting pointers to ints is unstable in const fn
+error[E0723]: casting pointers to ints is unstable in const fn (see issue #57563)
   --> $DIR/min_const_fn.rs:98:63
    |
 LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } }
    |                                                               ^^^^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: `if`, `match`, `&&` and `||` are not stable in const fn
+error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn (see issue #57563)
   --> $DIR/min_const_fn.rs:100:38
    |
 LL | const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } }
    |                                      ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: `if`, `match`, `&&` and `||` are not stable in const fn
+error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn (see issue #57563)
   --> $DIR/min_const_fn.rs:102:29
    |
 LL | const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn
    |                             ^^^^^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: `if`, `match`, `&&` and `||` are not stable in const fn
+error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn (see issue #57563)
   --> $DIR/min_const_fn.rs:104:44
    |
 LL | const fn foo36(a: bool, b: bool) -> bool { a && b }
    |                                            ^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: `if`, `match`, `&&` and `||` are not stable in const fn
+error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn (see issue #57563)
   --> $DIR/min_const_fn.rs:106:44
    |
 LL | const fn foo37(a: bool, b: bool) -> bool { a || b }
    |                                            ^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: mutable references in const fn are unstable
+error[E0723]: mutable references in const fn are unstable (see issue #57563)
   --> $DIR/min_const_fn.rs:108:14
    |
 LL | const fn inc(x: &mut i32) { *x += 1 }
    |              ^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: trait bounds other than `Sized` on const fn parameters are unstable
+error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable (see issue #57563)
   --> $DIR/min_const_fn.rs:113:6
    |
 LL | impl<T: std::fmt::Debug> Foo<T> {
    |      ^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: trait bounds other than `Sized` on const fn parameters are unstable
+error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable (see issue #57563)
   --> $DIR/min_const_fn.rs:118:6
    |
 LL | impl<T: std::fmt::Debug + Sized> Foo<T> {
    |      ^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: trait bounds other than `Sized` on const fn parameters are unstable
+error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable (see issue #57563)
   --> $DIR/min_const_fn.rs:123:6
    |
 LL | impl<T: Sync + Sized> Foo<T> {
    |      ^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: `impl Trait` in const fn is unstable
+error[E0723]: `impl Trait` in const fn is unstable (see issue #57563)
   --> $DIR/min_const_fn.rs:129:24
    |
 LL | const fn no_rpit2() -> AlanTuring<impl std::fmt::Debug> { AlanTuring(0) }
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: trait bounds other than `Sized` on const fn parameters are unstable
+error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable (see issue #57563)
   --> $DIR/min_const_fn.rs:131:34
    |
 LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
    |                                  ^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: trait bounds other than `Sized` on const fn parameters are unstable
+error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable (see issue #57563)
   --> $DIR/min_const_fn.rs:133:22
    |
 LL | const fn no_apit(_x: impl std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized`
    |                      ^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: `impl Trait` in const fn is unstable
+error[E0723]: `impl Trait` in const fn is unstable (see issue #57563)
   --> $DIR/min_const_fn.rs:134:23
    |
 LL | const fn no_rpit() -> impl std::fmt::Debug {} //~ ERROR `impl Trait` in const fn is unstable
    |                       ^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: trait bounds other than `Sized` on const fn parameters are unstable
+error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable (see issue #57563)
   --> $DIR/min_const_fn.rs:135:23
    |
 LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized`
    |                       ^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: trait bounds other than `Sized` on const fn parameters are unstable
+error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable (see issue #57563)
   --> $DIR/min_const_fn.rs:136:32
    |
 LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: trait bounds other than `Sized` on const fn parameters are unstable
+error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable (see issue #57563)
   --> $DIR/min_const_fn.rs:141:41
    |
 LL | const fn really_no_traits_i_mean_it() { (&() as &std::fmt::Debug, ()).1 }
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: function pointers in const fn are unstable
+error[E0723]: function pointers in const fn are unstable (see issue #57563)
   --> $DIR/min_const_fn.rs:144:21
    |
 LL | const fn no_fn_ptrs(_x: fn()) {}
    |                     ^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: function pointers in const fn are unstable
+error[E0723]: function pointers in const fn are unstable (see issue #57563)
   --> $DIR/min_const_fn.rs:146:27
    |
 LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
    |                           ^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
 error: aborting due to 36 previous errors
 
-For more information about this error, try `rustc --explain E0493`.
+Some errors occurred: E0493, E0723.
+For more information about an error, try `rustc --explain E0493`.
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr
index 8179cf795b48c..8ff963722cf15 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr
@@ -1,14 +1,19 @@
-error: trait bounds other than `Sized` on const fn parameters are unstable
+error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable (see issue #57563)
   --> $DIR/min_const_fn_dyn.rs:9:5
    |
 LL |     x.0.field;
    |     ^^^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: trait bounds other than `Sized` on const fn parameters are unstable
+error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable (see issue #57563)
   --> $DIR/min_const_fn_dyn.rs:12:66
    |
 LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
    |                                                                  ^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0723`.
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_fn_ptr.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_fn_ptr.stderr
index c1cb19180a5ee..8838ababe2c0e 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn_fn_ptr.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_fn_ptr.stderr
@@ -1,14 +1,19 @@
-error: function pointers in const fn are unstable
+error[E0723]: function pointers in const fn are unstable (see issue #57563)
   --> $DIR/min_const_fn_fn_ptr.rs:11:5
    |
 LL |     x.0.field;
    |     ^^^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: function pointers in const fn are unstable
+error[E0723]: function pointers in const fn are unstable (see issue #57563)
   --> $DIR/min_const_fn_fn_ptr.rs:14:59
    |
 LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasPtr { field }) }
    |                                                           ^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0723`.
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr
index 9640105d25c54..1e6f698b3c8e3 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr
@@ -1,26 +1,35 @@
-error: can only call other `min_const_fn` within a `min_const_fn`
+error[E0723]: can only call other `min_const_fn` within a `min_const_fn` (see issue #57563)
   --> $DIR/min_const_fn_libstd_stability.rs:15:25
    |
 LL | const fn bar() -> u32 { foo() } //~ ERROR can only call other `min_const_fn`
    |                         ^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: can only call other `min_const_fn` within a `min_const_fn`
+error[E0723]: can only call other `min_const_fn` within a `min_const_fn` (see issue #57563)
   --> $DIR/min_const_fn_libstd_stability.rs:22:26
    |
 LL | const fn bar2() -> u32 { foo2() } //~ ERROR can only call other `min_const_fn`
    |                          ^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: only int, `bool` and `char` operations are stable in const fn
+error[E0723]: only int, `bool` and `char` operations are stable in const fn (see issue #57563)
   --> $DIR/min_const_fn_libstd_stability.rs:26:26
    |
 LL | const fn bar3() -> u32 { (5f32 + 6f32) as u32 } //~ ERROR only int, `bool` and `char` operations
    |                          ^^^^^^^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: can only call other `min_const_fn` within a `min_const_fn`
+error[E0723]: can only call other `min_const_fn` within a `min_const_fn` (see issue #57563)
   --> $DIR/min_const_fn_libstd_stability.rs:34:32
    |
 LL | const fn bar2_gated() -> u32 { foo2_gated() } //~ ERROR can only call other `min_const_fn`
    |                                ^^^^^^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
 error: aborting due to 4 previous errors
 
+For more information about this error, try `rustc --explain E0723`.
diff --git a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr
index 049c25e71913d..07d10984392d8 100644
--- a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability.stderr
@@ -1,26 +1,35 @@
-error: can only call other `min_const_fn` within a `min_const_fn`
+error[E0723]: can only call other `min_const_fn` within a `min_const_fn` (see issue #57563)
   --> $DIR/min_const_unsafe_fn_libstd_stability.rs:15:41
    |
 LL | const unsafe fn bar() -> u32 { unsafe { foo() } } //~ ERROR can only call other `min_const_fn`
    |                                         ^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: can only call other `min_const_fn` within a `min_const_fn`
+error[E0723]: can only call other `min_const_fn` within a `min_const_fn` (see issue #57563)
   --> $DIR/min_const_unsafe_fn_libstd_stability.rs:22:42
    |
 LL | const unsafe fn bar2() -> u32 { unsafe { foo2() } } //~ ERROR can only call other `min_const_fn`
    |                                          ^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: only int, `bool` and `char` operations are stable in const fn
+error[E0723]: only int, `bool` and `char` operations are stable in const fn (see issue #57563)
   --> $DIR/min_const_unsafe_fn_libstd_stability.rs:26:33
    |
 LL | const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 } //~ ERROR only int, `bool` and `char` op
    |                                 ^^^^^^^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: can only call other `min_const_fn` within a `min_const_fn`
+error[E0723]: can only call other `min_const_fn` within a `min_const_fn` (see issue #57563)
   --> $DIR/min_const_unsafe_fn_libstd_stability.rs:34:48
    |
 LL | const unsafe fn bar2_gated() -> u32 { unsafe { foo2_gated() } } //~ ERROR can only call other
    |                                                ^^^^^^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
 error: aborting due to 4 previous errors
 
+For more information about this error, try `rustc --explain E0723`.
diff --git a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.stderr b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.stderr
index 89509f813e107..7cb8c6e62ec60 100644
--- a/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_unsafe_fn_libstd_stability2.stderr
@@ -1,20 +1,27 @@
-error: can only call other `min_const_fn` within a `min_const_fn`
+error[E0723]: can only call other `min_const_fn` within a `min_const_fn` (see issue #57563)
   --> $DIR/min_const_unsafe_fn_libstd_stability2.rs:15:32
    |
 LL | const unsafe fn bar() -> u32 { foo() } //~ ERROR can only call other `min_const_fn`
    |                                ^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: can only call other `min_const_fn` within a `min_const_fn`
+error[E0723]: can only call other `min_const_fn` within a `min_const_fn` (see issue #57563)
   --> $DIR/min_const_unsafe_fn_libstd_stability2.rs:22:33
    |
 LL | const unsafe fn bar2() -> u32 { foo2() } //~ ERROR can only call other `min_const_fn`
    |                                 ^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: can only call other `min_const_fn` within a `min_const_fn`
+error[E0723]: can only call other `min_const_fn` within a `min_const_fn` (see issue #57563)
   --> $DIR/min_const_unsafe_fn_libstd_stability2.rs:30:39
    |
 LL | const unsafe fn bar2_gated() -> u32 { foo2_gated() } //~ ERROR can only call other `min_const_fn`
    |                                       ^^^^^^^^^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
 error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0723`.
diff --git a/src/test/ui/consts/min_const_fn/mutable_borrow.stderr b/src/test/ui/consts/min_const_fn/mutable_borrow.stderr
index 5ce0f30dc6e1f..e5a3502a3dc52 100644
--- a/src/test/ui/consts/min_const_fn/mutable_borrow.stderr
+++ b/src/test/ui/consts/min_const_fn/mutable_borrow.stderr
@@ -1,14 +1,19 @@
-error: mutable references in const fn are unstable
+error[E0723]: mutable references in const fn are unstable (see issue #57563)
   --> $DIR/mutable_borrow.rs:3:9
    |
 LL |     let b = &mut a; //~ ERROR mutable references in const fn
    |         ^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: mutable references in const fn are unstable
+error[E0723]: mutable references in const fn are unstable (see issue #57563)
   --> $DIR/mutable_borrow.rs:12:13
    |
 LL |         let b = &mut a; //~ ERROR mutable references in const fn
    |             ^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0723`.
diff --git a/src/test/ui/consts/single_variant_match_ice.stderr b/src/test/ui/consts/single_variant_match_ice.stderr
index f5c2cb5e0e9dc..5272062ccfc14 100644
--- a/src/test/ui/consts/single_variant_match_ice.stderr
+++ b/src/test/ui/consts/single_variant_match_ice.stderr
@@ -10,12 +10,15 @@ error[E0019]: constant contains unimplemented expression type
 LL |     x => 42, //~ ERROR unimplemented expression type
    |     ^
 
-error: `if`, `match`, `&&` and `||` are not stable in const fn
+error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn (see issue #57563)
   --> $DIR/single_variant_match_ice.rs:18:13
    |
 LL |             Prob => 0x1, //~ ERROR `if`, `match`, `&&` and `||` are not stable in const fn
    |             ^^^^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
 error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0019`.
+Some errors occurred: E0019, E0723.
+For more information about an error, try `rustc --explain E0019`.
diff --git a/src/test/ui/issues/issue-37550.stderr b/src/test/ui/issues/issue-37550.stderr
index d2b03416cb73c..97160af43bee4 100644
--- a/src/test/ui/issues/issue-37550.stderr
+++ b/src/test/ui/issues/issue-37550.stderr
@@ -1,8 +1,11 @@
-error: function pointers in const fn are unstable
+error[E0723]: function pointers in const fn are unstable (see issue #57563)
   --> $DIR/issue-37550.rs:3:9
    |
 LL |     let x = || t; //~ ERROR function pointers in const fn are unstable
    |         ^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0723`.
diff --git a/src/test/ui/unsafe/ranged_ints2_const.stderr b/src/test/ui/unsafe/ranged_ints2_const.stderr
index 39a55190b17de..fb3841948f11f 100644
--- a/src/test/ui/unsafe/ranged_ints2_const.stderr
+++ b/src/test/ui/unsafe/ranged_ints2_const.stderr
@@ -1,14 +1,18 @@
-error: mutable references in const fn are unstable
+error[E0723]: mutable references in const fn are unstable (see issue #57563)
   --> $DIR/ranged_ints2_const.rs:11:9
    |
 LL |     let y = &mut x.0; //~ ERROR references in const fn are unstable
    |         ^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error: mutable references in const fn are unstable
+error[E0723]: mutable references in const fn are unstable (see issue #57563)
   --> $DIR/ranged_ints2_const.rs:18:9
    |
 LL |     let y = unsafe { &mut x.0 }; //~ ERROR mutable references in const fn are unstable
    |         ^
+   |
+   = help: add #![feature(const_fn)] to the crate attributes to enable
 
 error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
   --> $DIR/ranged_ints2_const.rs:11:13
@@ -20,4 +24,5 @@ LL |     let y = &mut x.0; //~ ERROR references in const fn are unstable
 
 error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0133`.
+Some errors occurred: E0133, E0723.
+For more information about an error, try `rustc --explain E0133`.

From 8a7df4f059d5a14bf4a3ecf938e383d01da9d3a8 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Tue, 5 Feb 2019 22:03:01 +0100
Subject: [PATCH 09/24] Fix documentation typo

---
 src/librustc_mir/diagnostics.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/librustc_mir/diagnostics.rs b/src/librustc_mir/diagnostics.rs
index 0858c0de3be41..2097cffd817cb 100644
--- a/src/librustc_mir/diagnostics.rs
+++ b/src/librustc_mir/diagnostics.rs
@@ -2388,14 +2388,14 @@ const fn foo() -> impl T { // error: `impl Trait` in const fn is unstable
 To enable this feature on a nightly version of rustc, add the `const_fn`
 feature flag:
 
-```compile_fail,E0723
+```
 #![feature(const_fn)]
 
 trait T {}
 
 impl T for () {}
 
-const fn foo() -> impl T { // error: `impl Trait` in const fn is unstable
+const fn foo() -> impl T {
     ()
 }
 ```

From 13bbba273c2a3d6a83c081ba3c2129f8d572c1b7 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Wed, 6 Feb 2019 11:23:10 +0100
Subject: [PATCH 10/24] remove now-unneeded raw ptr casts

---
 src/libcore/str/mod.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index b01cb688ee5c6..8c8f280f84794 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -1759,7 +1759,7 @@ mod traits {
         unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
             let ptr = slice.as_mut_ptr().add(self.start);
             let len = self.end - self.start;
-            super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr as *mut u8, len))
+            super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr, len))
         }
         #[inline]
         fn index(self, slice: &str) -> &Self::Output {
@@ -1822,7 +1822,7 @@ mod traits {
         #[inline]
         unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
             let ptr = slice.as_mut_ptr();
-            super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr as *mut u8, self.end))
+            super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr, self.end))
         }
         #[inline]
         fn index(self, slice: &str) -> &Self::Output {
@@ -1885,7 +1885,7 @@ mod traits {
         unsafe fn get_unchecked_mut(self, slice: &mut str) -> &mut Self::Output {
             let ptr = slice.as_mut_ptr().add(self.start);
             let len = slice.len() - self.start;
-            super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr as *mut u8, len))
+            super::from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr, len))
         }
         #[inline]
         fn index(self, slice: &str) -> &Self::Output {

From a996f2c8dcfd08b545374a0b6c0cc0c0c349ad30 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Wed, 6 Feb 2019 12:55:50 +0100
Subject: [PATCH 11/24] add tracking issue

---
 src/libcore/str/mod.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 8c8f280f84794..f95cd0dab43ab 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -2223,7 +2223,7 @@ impl str {
     /// modified in a way that it remains valid UTF-8.
     ///
     /// [`u8`]: primitive.u8.html
-    #[unstable(feature = "str_as_mut_ptr", issue = "0")]
+    #[unstable(feature = "str_as_mut_ptr", issue = "58215")]
     #[inline]
     pub fn as_mut_ptr(&mut self) -> *mut u8 {
         self as *mut str as *mut u8

From 66c894e07f95a324a39bb4c281c8db4c8842689b Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Thu, 7 Feb 2019 17:55:25 +0100
Subject: [PATCH 12/24] also fix bad use of shared ref in split_at_mut

---
 src/libcore/str/mod.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index f95cd0dab43ab..6793b16481e01 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -2516,7 +2516,7 @@ impl str {
         // is_char_boundary checks that the index is in [0, .len()]
         if self.is_char_boundary(mid) {
             let len = self.len();
-            let ptr = self.as_ptr() as *mut u8;
+            let ptr = self.as_mut_ptr();
             unsafe {
                 (from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr, mid)),
                  from_utf8_unchecked_mut(slice::from_raw_parts_mut(

From f06af1ff178014dadd62391a4a06e7fff8f2a6a1 Mon Sep 17 00:00:00 2001
From: Harald Hoyer <harald@redhat.com>
Date: Thu, 7 Feb 2019 16:10:34 +0100
Subject: [PATCH 13/24] impl iter_sources() and iter_chain() for dyn Error

Examples:

```rust
let next_error_type_a = err
    .iter_chain()
    .filter_map(Error::downcast_ref::<ErrorTypeA>)
    .next();
```

```rust
let source_root_error = err.iter_chain().last();
```

Credit for the ErrorIter goes to Tim Diekmann
https://www.reddit.com/r/rust/comments/aj3lpg/is_an_iterator_impl_over_errorsource_possible/
---
 src/libstd/error.rs | 152 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 152 insertions(+)

diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index 50415d9aeb9c8..de27333d28c64 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -667,6 +667,158 @@ impl dyn Error {
             Err(self)
         }
     }
+
+    /// Returns an iterator starting with the current error and continuing with
+    /// recursively calling [`source`].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(error_iter)]
+    /// use std::error::Error;
+    /// use std::fmt;
+    ///
+    /// #[derive(Debug)]
+    /// struct A;
+    ///
+    /// #[derive(Debug)]
+    /// struct B(Option<Box<dyn Error + 'static>>);
+    ///
+    /// impl fmt::Display for A {
+    ///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    ///         write!(f, "A")
+    ///     }
+    /// }
+    ///
+    /// impl fmt::Display for B {
+    ///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    ///         write!(f, "B")
+    ///     }
+    /// }
+    ///
+    /// impl Error for A {}
+    ///
+    /// impl Error for B {
+    ///     fn source(&self) -> Option<&(dyn Error + 'static)> {
+    ///         self.0.as_ref().map(|e| e.as_ref())
+    ///     }
+    /// }
+    ///
+    /// let b = B(Some(Box::new(A)));
+    ///
+    /// // let err : Box<Error> = b.into(); // or
+    /// let err = &b as &(dyn Error);
+    ///
+    /// let mut iter = err.iter_chain();
+    ///
+    /// assert_eq!("B".to_string(), iter.next().unwrap().to_string());
+    /// assert_eq!("A".to_string(), iter.next().unwrap().to_string());
+    /// assert!(iter.next().is_none());
+    /// assert!(iter.next().is_none());
+    /// ```
+    ///
+    /// [`source`]: trait.Error.html#method.source
+    #[unstable(feature = "error_iter", issue = "58289")]
+    #[inline]
+    pub fn iter_chain(&self) -> ErrorIter {
+        ErrorIter {
+            current: Some(self),
+        }
+    }
+
+    /// Returns an iterator starting with the [`source`] of this error
+    /// and continuing with recursively calling [`source`].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(error_iter)]
+    /// use std::error::Error;
+    /// use std::fmt;
+    ///
+    /// #[derive(Debug)]
+    /// struct A;
+    ///
+    /// #[derive(Debug)]
+    /// struct B(Option<Box<dyn Error + 'static>>);
+    ///
+    /// #[derive(Debug)]
+    /// struct C(Option<Box<dyn Error + 'static>>);
+    ///
+    /// impl fmt::Display for A {
+    ///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    ///         write!(f, "A")
+    ///     }
+    /// }
+    ///
+    /// impl fmt::Display for B {
+    ///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    ///         write!(f, "B")
+    ///     }
+    /// }
+    ///
+    /// impl fmt::Display for C {
+    ///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    ///         write!(f, "C")
+    ///     }
+    /// }
+    ///
+    /// impl Error for A {}
+    ///
+    /// impl Error for B {
+    ///     fn source(&self) -> Option<&(dyn Error + 'static)> {
+    ///         self.0.as_ref().map(|e| e.as_ref())
+    ///     }
+    /// }
+    ///
+    /// impl Error for C {
+    ///     fn source(&self) -> Option<&(dyn Error + 'static)> {
+    ///         self.0.as_ref().map(|e| e.as_ref())
+    ///     }
+    /// }
+    ///
+    /// let b = B(Some(Box::new(A)));
+    /// let c = C(Some(Box::new(b)));
+    ///
+    /// // let err : Box<Error> = c.into(); // or
+    /// let err = &c as &(dyn Error);
+    ///
+    /// let mut iter = err.iter_sources();
+    ///
+    /// assert_eq!("B".to_string(), iter.next().unwrap().to_string());
+    /// assert_eq!("A".to_string(), iter.next().unwrap().to_string());
+    /// assert!(iter.next().is_none());
+    /// assert!(iter.next().is_none());
+    /// ```
+    ///
+    /// [`source`]: trait.Error.html#method.source
+    #[inline]
+    #[unstable(feature = "error_iter", issue = "58289")]
+    pub fn iter_sources(&self) -> ErrorIter {
+        ErrorIter {
+            current: self.source(),
+        }
+    }
+}
+
+/// An iterator over [`Error`]
+///
+/// [`Error`]: trait.Error.html
+#[unstable(feature = "error_iter", issue = "58289")]
+#[derive(Copy, Clone, Debug)]
+pub struct ErrorIter<'a> {
+    current: Option<&'a (dyn Error + 'static)>,
+}
+
+#[unstable(feature = "error_iter", issue = "58289")]
+impl<'a> Iterator for ErrorIter<'a> {
+    type Item = &'a (dyn Error + 'static);
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let current = self.current;
+        self.current = self.current.and_then(Error::source);
+        current
+    }
 }
 
 impl dyn Error + Send {

From 3a1a704903e5e671032811a2dc6fc958663bf4d7 Mon Sep 17 00:00:00 2001
From: ljedrz <ljedrz@gmail.com>
Date: Mon, 4 Feb 2019 09:38:11 +0100
Subject: [PATCH 14/24] cleanup: rename node_id_to_type(_opt)

---
 .../infer/error_reporting/need_type_info.rs   |  4 ++--
 .../error_reporting/nice_region_error/util.rs |  2 +-
 src/librustc/middle/dead.rs                   |  2 +-
 src/librustc/middle/intrinsicck.rs            |  2 +-
 src/librustc/middle/mem_categorization.rs     |  4 ++--
 src/librustc/ty/context.rs                    | 21 ++++++++-----------
 src/librustc/ty/item_path.rs                  |  1 -
 .../borrowck/gather_loans/mod.rs              |  2 +-
 src/librustc_lint/builtin.rs                  |  4 ++--
 src/librustc_lint/types.rs                    |  6 +++---
 src/librustc_metadata/encoder.rs              |  2 +-
 .../borrow_check/error_reporting.rs           |  2 +-
 .../borrow_check/nll/universal_regions.rs     |  2 +-
 src/librustc_mir/build/mod.rs                 |  4 ++--
 src/librustc_mir/hair/cx/block.rs             |  2 +-
 src/librustc_mir/hair/cx/expr.rs              | 14 ++++++-------
 src/librustc_mir/hair/pattern/check_match.rs  |  6 +++---
 src/librustc_mir/hair/pattern/mod.rs          |  6 +++---
 src/librustc_mir/hair/util.rs                 |  2 +-
 src/librustc_passes/rvalue_promotion.rs       |  4 ++--
 src/librustc_privacy/lib.rs                   |  4 ++--
 src/librustc_save_analysis/dump_visitor.rs    |  8 +++----
 src/librustc_typeck/check/demand.rs           |  2 +-
 src/librustc_typeck/collect.rs                |  2 +-
 24 files changed, 52 insertions(+), 56 deletions(-)

diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs
index fac498bd6dd78..e63fa230b3eba 100644
--- a/src/librustc/infer/error_reporting/need_type_info.rs
+++ b/src/librustc/infer/error_reporting/need_type_info.rs
@@ -16,9 +16,9 @@ struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
 }
 
 impl<'a, 'gcx, 'tcx> FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
-    fn node_matches_type(&mut self, node_id: HirId) -> bool {
+    fn node_matches_type(&mut self, hir_id: HirId) -> bool {
         let ty_opt = self.infcx.in_progress_tables.and_then(|tables| {
-            tables.borrow().node_id_to_type_opt(node_id)
+            tables.borrow().node_type_opt(hir_id)
         });
         match ty_opt {
             Some(ty) => {
diff --git a/src/librustc/infer/error_reporting/nice_region_error/util.rs b/src/librustc/infer/error_reporting/nice_region_error/util.rs
index f73f8d8bb82be..6db1bc382afe9 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/util.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/util.rs
@@ -64,7 +64,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
                             // May return None; sometimes the tables are not yet populated.
                             let ty_hir_id = fn_decl.inputs[index].hir_id;
                             let arg_ty_span = hir.span(hir.hir_to_node_id(ty_hir_id));
-                            let ty = tables.node_id_to_type_opt(arg.hir_id)?;
+                            let ty = tables.node_type_opt(arg.hir_id)?;
                             let mut found_anon_region = false;
                             let new_arg_ty = self.tcx().fold_regions(&ty, &mut false, |r, _| {
                                 if *r == *anon_region {
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 6dffe8efba612..569968bd6d4bf 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -112,7 +112,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
 
     fn handle_field_pattern_match(&mut self, lhs: &hir::Pat, def: Def,
                                   pats: &[source_map::Spanned<hir::FieldPat>]) {
-        let variant = match self.tables.node_id_to_type(lhs.hir_id).sty {
+        let variant = match self.tables.node_type(lhs.hir_id).sty {
             ty::Adt(adt, _) => adt.variant_of_def(def),
             _ => span_bug!(lhs.span, "non-ADT in struct pattern")
         };
diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs
index ee361e9776313..ce20ca39533b1 100644
--- a/src/librustc/middle/intrinsicck.rs
+++ b/src/librustc/middle/intrinsicck.rs
@@ -165,7 +165,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ExprVisitor<'a, 'tcx> {
         };
         if let Def::Fn(did) = def {
             if self.def_id_is_transmute(did) {
-                let typ = self.tables.node_id_to_type(expr.hir_id);
+                let typ = self.tables.node_type(expr.hir_id);
                 let sig = typ.fn_sig(self.tcx);
                 let from = sig.inputs().skip_binder()[0];
                 let to = *sig.output().skip_binder();
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 04e4a0b39a2ca..edc2a112b95ed 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -174,7 +174,7 @@ pub enum Note {
 // which the value is stored.
 //
 // *WARNING* The field `cmt.type` is NOT necessarily the same as the
-// result of `node_id_to_type(cmt.id)`.
+// result of `node_type(cmt.id)`.
 //
 // (FIXME: rewrite the following comment given that `@x` managed
 // pointers have been obsolete for quite some time.)
@@ -497,7 +497,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
                    hir_id: hir::HirId)
                    -> McResult<Ty<'tcx>> {
         self.resolve_type_vars_or_error(hir_id,
-                                        self.tables.node_id_to_type_opt(hir_id))
+                                        self.tables.node_type_opt(hir_id))
     }
 
     pub fn expr_ty(&self, expr: &hir::Expr) -> McResult<Ty<'tcx>> {
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index c955b042e44d1..6934373e981c8 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -525,17 +525,14 @@ impl<'tcx> TypeckTables<'tcx> {
         }
     }
 
-    pub fn node_id_to_type(&self, id: hir::HirId) -> Ty<'tcx> {
-        self.node_id_to_type_opt(id).unwrap_or_else(||
-            bug!("node_id_to_type: no type for node `{}`",
-                 tls::with(|tcx| {
-                     let id = tcx.hir().hir_to_node_id(id);
-                     tcx.hir().node_to_string(id)
-                 }))
+    pub fn node_type(&self, id: hir::HirId) -> Ty<'tcx> {
+        self.node_type_opt(id).unwrap_or_else(||
+            bug!("node_type: no type for node `{}`",
+                 tls::with(|tcx| tcx.hir().hir_to_string(id)))
         )
     }
 
-    pub fn node_id_to_type_opt(&self, id: hir::HirId) -> Option<Ty<'tcx>> {
+    pub fn node_type_opt(&self, id: hir::HirId) -> Option<Ty<'tcx>> {
         validate_hir_id_for_typeck_tables(self.local_id_root, id, false);
         self.node_types.get(&id.local_id).cloned()
     }
@@ -560,11 +557,11 @@ impl<'tcx> TypeckTables<'tcx> {
     // Returns the type of a pattern as a monotype. Like @expr_ty, this function
     // doesn't provide type parameter substitutions.
     pub fn pat_ty(&self, pat: &hir::Pat) -> Ty<'tcx> {
-        self.node_id_to_type(pat.hir_id)
+        self.node_type(pat.hir_id)
     }
 
     pub fn pat_ty_opt(&self, pat: &hir::Pat) -> Option<Ty<'tcx>> {
-        self.node_id_to_type_opt(pat.hir_id)
+        self.node_type_opt(pat.hir_id)
     }
 
     // Returns the type of an expression as a monotype.
@@ -578,11 +575,11 @@ impl<'tcx> TypeckTables<'tcx> {
     // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize"
     // instead of "fn(ty) -> T with T = isize".
     pub fn expr_ty(&self, expr: &hir::Expr) -> Ty<'tcx> {
-        self.node_id_to_type(expr.hir_id)
+        self.node_type(expr.hir_id)
     }
 
     pub fn expr_ty_opt(&self, expr: &hir::Expr) -> Option<Ty<'tcx>> {
-        self.node_id_to_type_opt(expr.hir_id)
+        self.node_type_opt(expr.hir_id)
     }
 
     pub fn adjustments(&self) -> LocalTableInContext<'_, Vec<ty::adjustment::Adjustment<'tcx>>> {
diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs
index 8214c8bacc704..df09cf629d407 100644
--- a/src/librustc/ty/item_path.rs
+++ b/src/librustc/ty/item_path.rs
@@ -1,4 +1,3 @@
-use crate::hir;
 use crate::hir::map::DefPathData;
 use crate::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use crate::ty::{self, DefIdTree, Ty, TyCtxt};
diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs
index c21a43bc68333..ee3aabe89d004 100644
--- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs
+++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs
@@ -149,7 +149,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> {
     fn decl_without_init(&mut self, id: ast::NodeId, _span: Span) {
         let ty = self.bccx
                      .tables
-                     .node_id_to_type(self.bccx.tcx.hir().node_to_hir_id(id));
+                     .node_type(self.bccx.tcx.hir().node_to_hir_id(id));
         gather_moves::gather_decl(self.bccx, &self.move_data, id, ty);
     }
 }
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index cbcc7f3574d03..442e54dc48696 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -155,7 +155,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoxPointers {
     }
 
     fn check_expr(&mut self, cx: &LateContext<'_, '_>, e: &hir::Expr) {
-        let ty = cx.tables.node_id_to_type(e.hir_id);
+        let ty = cx.tables.node_type(e.hir_id);
         self.check_heap_type(cx, e.span, ty);
     }
 }
@@ -1000,7 +1000,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes {
                 if !def_id_is_transmute(cx, did) {
                     return None;
                 }
-                let sig = cx.tables.node_id_to_type(expr.hir_id).fn_sig(cx.tcx);
+                let sig = cx.tables.node_type(expr.hir_id).fn_sig(cx.tcx);
                 let from = sig.inputs().skip_binder()[0];
                 let to = *sig.output().skip_binder();
                 return Some((&from.sty, &to.sty));
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index f6b7ccfe2ecd8..3e02c14fc1baf 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -85,7 +85,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
                 }
             }
             hir::ExprKind::Lit(ref lit) => {
-                match cx.tables.node_id_to_type(e.hir_id).sty {
+                match cx.tables.node_type(e.hir_id).sty {
                     ty::Int(t) => {
                         match lit.node {
                             ast::LitKind::Int(v, ast::LitIntType::Signed(_)) |
@@ -257,7 +257,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
             // Normalize the binop so that the literal is always on the RHS in
             // the comparison
             let norm_binop = if swap { rev_binop(binop) } else { binop };
-            match cx.tables.node_id_to_type(expr.hir_id).sty {
+            match cx.tables.node_type(expr.hir_id).sty {
                 ty::Int(int_ty) => {
                     let (min, max) = int_ty_range(int_ty);
                     let lit_val: i128 = match lit.node {
@@ -400,7 +400,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
                 repr_str, val, t, actually, t
             ));
             if let Some(sugg_ty) =
-                get_type_suggestion(&cx.tables.node_id_to_type(expr.hir_id).sty, val, negative)
+                get_type_suggestion(&cx.tables.node_type(expr.hir_id).sty, val, negative)
             {
                 if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') {
                     let (sans_suffix, _) = repr_str.split_at(pos);
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index d68ab9750b970..ec49ef3f6e046 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -1338,7 +1338,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
         let tables = self.tcx.typeck_tables_of(def_id);
         let node_id = self.tcx.hir().as_local_node_id(def_id).unwrap();
         let hir_id = self.tcx.hir().node_to_hir_id(node_id);
-        let kind = match tables.node_id_to_type(hir_id).sty {
+        let kind = match tables.node_type(hir_id).sty {
             ty::Generator(def_id, ..) => {
                 let layout = self.tcx.generator_layout(def_id);
                 let data = GeneratorData {
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index afb26963217ff..c7d3bf14f5e0c 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -1178,7 +1178,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         let escapes_from = if tcx.is_closure(self.mir_def_id) {
             let tables = tcx.typeck_tables_of(self.mir_def_id);
             let mir_hir_id = tcx.hir().def_index_to_hir_id(self.mir_def_id.index);
-            match tables.node_id_to_type(mir_hir_id).sty {
+            match tables.node_type(mir_hir_id).sty {
                 ty::Closure(..) => "closure",
                 ty::Generator(..) => "generator",
                 _ => bug!("Closure body doesn't have a closure or generator type"),
diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs
index 0a214e60bdd78..cdd0c6f807595 100644
--- a/src/librustc_mir/borrow_check/nll/universal_regions.rs
+++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs
@@ -482,7 +482,7 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> {
                     tcx.type_of(closure_base_def_id)
                 } else {
                     let tables = tcx.typeck_tables_of(self.mir_def_id);
-                    tables.node_id_to_type(self.mir_hir_id)
+                    tables.node_type(self.mir_hir_id)
                 };
 
                 debug!("defining_ty (pre-replacement): {:?}", defining_ty);
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index a52b032aeb508..dfe9c16cb5893 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -92,7 +92,7 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t
                     Some(ArgInfo(liberated_closure_env_ty(tcx, id, body_id), None, None, None))
                 }
                 ty::Generator(..) => {
-                    let gen_ty = tcx.body_tables(body_id).node_id_to_type(fn_hir_id);
+                    let gen_ty = tcx.body_tables(body_id).node_type(fn_hir_id);
                     Some(ArgInfo(gen_ty, None, None, None))
                 }
                 _ => None,
@@ -263,7 +263,7 @@ fn liberated_closure_env_ty<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
                                             body_id: hir::BodyId)
                                             -> Ty<'tcx> {
     let closure_expr_hir_id = tcx.hir().node_to_hir_id(closure_expr_id);
-    let closure_ty = tcx.body_tables(body_id).node_id_to_type(closure_expr_hir_id);
+    let closure_ty = tcx.body_tables(body_id).node_type(closure_expr_hir_id);
 
     let (closure_def_id, closure_substs) = match closure_ty.sty {
         ty::Closure(closure_def_id, closure_substs) => (closure_def_id, closure_substs),
diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs
index c24cf956504da..4e7bfbc4ab5d2 100644
--- a/src/librustc_mir/hair/cx/block.rs
+++ b/src/librustc_mir/hair/cx/block.rs
@@ -115,7 +115,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
 pub fn to_expr_ref<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                                    block: &'tcx hir::Block)
                                    -> ExprRef<'tcx> {
-    let block_ty = cx.tables().node_id_to_type(block.hir_id);
+    let block_ty = cx.tables().node_type(block.hir_id);
     let temp_lifetime = cx.region_scope_tree.temporary_scope(block.hir_id.local_id);
     let expr = Expr {
         ty: block_ty,
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index 7e1365f5dc12d..10d04a80d7341 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -304,7 +304,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                     }
                 } else {
                     ExprKind::Call {
-                        ty: cx.tables().node_id_to_type(fun.hir_id),
+                        ty: cx.tables().node_type(fun.hir_id),
                         fun: fun.to_ref(),
                         args: args.to_ref(),
                         from_hir_call: true,
@@ -677,7 +677,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                     let def = cx.tables().qpath_def(qpath, source.hir_id);
                     cx
                         .tables()
-                        .node_id_to_type(source.hir_id)
+                        .node_type(source.hir_id)
                         .ty_adt_def()
                         .and_then(|adt_def| {
                         match def {
@@ -919,7 +919,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
             debug!("convert_path_expr: user_ty={:?}", user_ty);
             ExprKind::Literal {
                 literal: cx.tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::zero_sized(
-                    cx.tables().node_id_to_type(expr.hir_id),
+                    cx.tables().node_type(expr.hir_id),
                 ))),
                 user_ty,
             }
@@ -940,7 +940,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
             let user_provided_types = cx.tables.user_provided_types();
             let user_provided_type = user_provided_types.get(expr.hir_id).map(|u_ty| *u_ty);
             debug!("convert_path_expr: user_provided_type={:?}", user_provided_type);
-            match cx.tables().node_id_to_type(expr.hir_id).sty {
+            match cx.tables().node_type(expr.hir_id).sty {
                 // A unit struct/variant which is used as a value.
                 // We return a completely different ExprKind here to account for this special case.
                 ty::Adt(adt_def, substs) => {
@@ -980,11 +980,11 @@ fn convert_var<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                    index,
                    closure_expr_id);
             let var_hir_id = cx.tcx.hir().node_to_hir_id(var_id);
-            let var_ty = cx.tables().node_id_to_type(var_hir_id);
+            let var_ty = cx.tables().node_type(var_hir_id);
 
             // FIXME free regions in closures are not right
             let closure_ty = cx.tables()
-                               .node_id_to_type(cx.tcx.hir().node_to_hir_id(closure_expr_id));
+                               .node_type(cx.tcx.hir().node_to_hir_id(closure_expr_id));
 
             // FIXME we're just hard-coding the idea that the
             // signature will be &self or &mut self and hence will
@@ -1188,7 +1188,7 @@ fn capture_freevar<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
     };
     let upvar_capture = cx.tables().upvar_capture(upvar_id);
     let temp_lifetime = cx.region_scope_tree.temporary_scope(closure_expr.hir_id.local_id);
-    let var_ty = cx.tables().node_id_to_type(var_hir_id);
+    let var_ty = cx.tables().node_type(var_hir_id);
     let captured_var = Expr {
         temp_lifetime,
         ty: var_ty,
diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs
index 978051aab591b..5616a5c2feeba 100644
--- a/src/librustc_mir/hair/pattern/check_match.rs
+++ b/src/librustc_mir/hair/pattern/check_match.rs
@@ -202,7 +202,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
 
             // Then, if the match has no arms, check whether the scrutinee
             // is uninhabited.
-            let pat_ty = self.tables.node_id_to_type(scrut.hir_id);
+            let pat_ty = self.tables.node_type(scrut.hir_id);
             let module = self.tcx.hir().get_module_parent(scrut.id);
             if inlined_arms.is_empty() {
                 let scrutinee_is_uninhabited = if self.tcx.features().exhaustive_patterns {
@@ -235,7 +235,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
                 .flat_map(|arm| &arm.0)
                 .map(|pat| smallvec![pat.0])
                 .collect();
-            let scrut_ty = self.tables.node_id_to_type(scrut.hir_id);
+            let scrut_ty = self.tables.node_type(scrut.hir_id);
             check_exhaustive(cx, scrut_ty, scrut.span, &matrix);
         })
     }
@@ -507,7 +507,7 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor<'_, '_>,
                 if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) {
                     match bm {
                         ty::BindByValue(..) => {
-                            let pat_ty = cx.tables.node_id_to_type(p.hir_id);
+                            let pat_ty = cx.tables.node_type(p.hir_id);
                             if !pat_ty.is_copy_modulo_regions(cx.tcx, cx.param_env, pat.span) {
                                 check_move(p, sub.as_ref().map(|p| &**p), span_vec);
                             }
diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs
index 84d8f32954c81..18e1af27bab38 100644
--- a/src/librustc_mir/hair/pattern/mod.rs
+++ b/src/librustc_mir/hair/pattern/mod.rs
@@ -406,7 +406,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
     }
 
     fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat) -> Pattern<'tcx> {
-        let mut ty = self.tables.node_id_to_type(pat.hir_id);
+        let mut ty = self.tables.node_type(pat.hir_id);
 
         let kind = match pat.node {
             PatKind::Wild => PatternKind::Wild,
@@ -539,7 +539,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
             }
 
             PatKind::Binding(_, id, _, ident, ref sub) => {
-                let var_ty = self.tables.node_id_to_type(pat.hir_id);
+                let var_ty = self.tables.node_type(pat.hir_id);
                 if let ty::Error = var_ty.sty {
                     // Avoid ICE
                     return Pattern { span: pat.span, ty, kind: Box::new(PatternKind::Wild) };
@@ -773,7 +773,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
                   id: hir::HirId,
                   span: Span)
                   -> Pattern<'tcx> {
-        let ty = self.tables.node_id_to_type(id);
+        let ty = self.tables.node_type(id);
         let def = self.tables.qpath_def(qpath, id);
         let is_associated_const = match def {
             Def::AssociatedConst(_) => true,
diff --git a/src/librustc_mir/hair/util.rs b/src/librustc_mir/hair/util.rs
index cb4a72387fa16..4618cd42686fa 100644
--- a/src/librustc_mir/hair/util.rs
+++ b/src/librustc_mir/hair/util.rs
@@ -16,7 +16,7 @@ crate trait UserAnnotatedTyHelpers<'gcx: 'tcx, 'tcx> {
         let user_provided_types = self.tables().user_provided_types();
         let mut user_ty = *user_provided_types.get(hir_id)?;
         debug!("user_subts_applied_to_ty_of_hir_id: user_ty={:?}", user_ty);
-        match &self.tables().node_id_to_type(hir_id).sty {
+        match &self.tables().node_type(hir_id).sty {
             ty::Adt(adt_def, ..) => {
                 if let UserType::TypeOf(ref mut did, _) = &mut user_ty.value {
                     *did = adt_def.did;
diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs
index 8d33fef5303ed..7f245c48166d6 100644
--- a/src/librustc_passes/rvalue_promotion.rs
+++ b/src/librustc_passes/rvalue_promotion.rs
@@ -244,7 +244,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
     }
 
     fn check_expr(&mut self, ex: &'tcx hir::Expr) -> Promotability {
-        let node_ty = self.tables.node_id_to_type(ex.hir_id);
+        let node_ty = self.tables.node_type(ex.hir_id);
         let mut outer = check_expr_kind(self, ex, node_ty);
         outer &= check_adjustments(self, ex);
 
@@ -306,7 +306,7 @@ fn check_expr_kind<'a, 'tcx>(
             if v.tables.is_method_call(e) {
                 return NotPromotable;
             }
-            match v.tables.node_id_to_type(lhs.hir_id).sty {
+            match v.tables.node_type(lhs.hir_id).sty {
                 ty::RawPtr(_) | ty::FnPtr(..) => {
                     assert!(op.node == hir::BinOpKind::Eq || op.node == hir::BinOpKind::Ne ||
                             op.node == hir::BinOpKind::Le || op.node == hir::BinOpKind::Lt ||
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 14a0922c47740..c395dffdc9799 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -932,7 +932,7 @@ impl<'a, 'tcx> TypePrivacyVisitor<'a, 'tcx> {
     // Take node-id of an expression or pattern and check its type for privacy.
     fn check_expr_pat_type(&mut self, id: hir::HirId, span: Span) -> bool {
         self.span = span;
-        if self.visit(self.tables.node_id_to_type(id)) || self.visit(self.tables.node_substs(id)) {
+        if self.visit(self.tables.node_type(id)) || self.visit(self.tables.node_substs(id)) {
             return true;
         }
         if let Some(adjustments) = self.tables.adjustments().get(id) {
@@ -979,7 +979,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
         self.span = hir_ty.span;
         if self.in_body {
             // Types in bodies.
-            if self.visit(self.tables.node_id_to_type(hir_ty.hir_id)) {
+            if self.visit(self.tables.node_type(hir_ty.hir_id)) {
                 return;
             }
         } else {
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 1a49056bc7f26..0bb1ce9e4bde9 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -245,7 +245,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
 
             for (id, ident, ..) in collector.collected_idents {
                 let hir_id = self.tcx.hir().node_to_hir_id(id);
-                let typ = match self.save_ctxt.tables.node_id_to_type_opt(hir_id) {
+                let typ = match self.save_ctxt.tables.node_type_opt(hir_id) {
                     Some(s) => s.to_string(),
                     None => continue,
                 };
@@ -863,7 +863,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
             PatKind::Struct(ref _path, ref fields, _) => {
                 // FIXME do something with _path?
                 let hir_id = self.tcx.hir().node_to_hir_id(p.id);
-                let adt = match self.save_ctxt.tables.node_id_to_type_opt(hir_id) {
+                let adt = match self.save_ctxt.tables.node_type_opt(hir_id) {
                     Some(ty) => ty.ty_adt_def().unwrap(),
                     None => {
                         visit::walk_pat(self, p);
@@ -910,7 +910,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
                     let hir_id = self.tcx.hir().node_to_hir_id(id);
                     let typ = self.save_ctxt
                         .tables
-                        .node_id_to_type_opt(hir_id)
+                        .node_type_opt(hir_id)
                         .map(|t| t.to_string())
                         .unwrap_or_default();
                     value.push_str(": ");
@@ -979,7 +979,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
                 _ => String::new(),
             };
             let hir_id = self.tcx.hir().node_to_hir_id(id);
-            let typ = match self.save_ctxt.tables.node_id_to_type_opt(hir_id) {
+            let typ = match self.save_ctxt.tables.node_type_opt(hir_id) {
                 Some(typ) => {
                     let typ = typ.to_string();
                     if !value.is_empty() {
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index 0d4690c83170a..cc04f84440af1 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -224,7 +224,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         node: hir::ExprKind::MethodCall(path, span, expr),
                         ..
                     })), 1) = (self.tcx.hir().find(parent), decl.inputs.len()) {
-                        let self_ty = self.tables.borrow().node_id_to_type(expr[0].hir_id);
+                        let self_ty = self.tables.borrow().node_type(expr[0].hir_id);
                         let self_ty = format!("{:?}", self_ty);
                         let name = path.ident.as_str();
                         let is_as_ref_able = (
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 9dc74c5d63a4e..1c45a75cf4052 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -1253,7 +1253,7 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Ty<'tcx> {
         }) => {
             if gen.is_some() {
                 let hir_id = tcx.hir().node_to_hir_id(node_id);
-                return tcx.typeck_tables_of(def_id).node_id_to_type(hir_id);
+                return tcx.typeck_tables_of(def_id).node_type(hir_id);
             }
 
             let substs = ty::ClosureSubsts {

From eb669b3a83dc1c1195ade3bff7f237afdd569ba2 Mon Sep 17 00:00:00 2001
From: ljedrz <ljedrz@gmail.com>
Date: Thu, 7 Feb 2019 12:35:40 +0100
Subject: [PATCH 15/24] cleanup: remove hir_path_str

---
 src/librustc/ty/item_path.rs | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs
index df09cf629d407..388eafb826fb1 100644
--- a/src/librustc/ty/item_path.rs
+++ b/src/librustc/ty/item_path.rs
@@ -76,11 +76,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         self.item_path_str(self.hir().local_def_id(id))
     }
 
-    // FIXME(@ljedrz): replace the NodeId variant
-    pub fn hir_path_str(self, id: hir::HirId) -> String {
-        self.item_path_str(self.hir().local_def_id_from_hir_id(id))
-    }
-
     /// Returns a string identifying this def-id. This string is
     /// suitable for user output. It always begins with a crate identifier.
     pub fn absolute_item_path_str(self, def_id: DefId) -> String {

From b284c8d608d0101276b9503d7fa1a9a57ce1d472 Mon Sep 17 00:00:00 2001
From: king6cong <king6cong@gmail.com>
Date: Thu, 17 Jan 2019 17:34:25 +0800
Subject: [PATCH 16/24] Doc rewording

---
 src/libstd/macros.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index b87257188df10..2431ae80554c3 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -8,7 +8,7 @@
 ///
 /// This allows a program to terminate immediately and provide feedback
 /// to the caller of the program. `panic!` should be used when a program reaches
-/// an unrecoverable problem.
+/// an unrecoverable state.
 ///
 /// This macro is the perfect way to assert conditions in example code and in
 /// tests.  `panic!` is closely tied with the `unwrap` method of both [`Option`]

From 04f425d2c31ea0ef022793a3fdcb8af84d471b86 Mon Sep 17 00:00:00 2001
From: Michael Woerister <michaelwoerister@posteo>
Date: Fri, 1 Feb 2019 15:15:43 +0100
Subject: [PATCH 17/24] Stabilize linker-plugin based LTO.

---
 src/librustc/session/config.rs                | 44 ++++++++++---------
 src/librustc/session/mod.rs                   |  2 +-
 src/librustc_codegen_llvm/back/link.rs        |  4 +-
 src/librustc_codegen_llvm/back/lto.rs         |  2 +-
 src/librustc_codegen_llvm/back/write.rs       |  2 +-
 src/librustc_codegen_llvm/consts.rs           |  6 +--
 src/librustc_codegen_ssa/back/linker.rs       | 26 +++++------
 src/librustc_codegen_ssa/back/write.rs        | 10 ++---
 .../codegen/no-dllimport-w-cross-lang-lto.rs  |  2 +-
 src/test/codegen/target-cpu-on-functions.rs   |  2 +-
 .../cross-lang-lto-clang/Makefile             |  4 +-
 .../cross-lang-lto-upstream-rlibs/Makefile    | 10 ++---
 .../run-make-fulldeps/cross-lang-lto/Makefile |  6 +--
 13 files changed, 61 insertions(+), 59 deletions(-)

diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 1a92f2c0f7aa1..2130314b5eae6 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -96,18 +96,18 @@ pub enum LtoCli {
 }
 
 #[derive(Clone, PartialEq, Hash)]
-pub enum CrossLangLto {
+pub enum LinkerPluginLto {
     LinkerPlugin(PathBuf),
     LinkerPluginAuto,
     Disabled
 }
 
-impl CrossLangLto {
+impl LinkerPluginLto {
     pub fn enabled(&self) -> bool {
         match *self {
-            CrossLangLto::LinkerPlugin(_) |
-            CrossLangLto::LinkerPluginAuto => true,
-            CrossLangLto::Disabled => false,
+            LinkerPluginLto::LinkerPlugin(_) |
+            LinkerPluginLto::LinkerPluginAuto => true,
+            LinkerPluginLto::Disabled => false,
         }
     }
 }
@@ -812,7 +812,7 @@ macro_rules! options {
         pub const parse_lto: Option<&str> =
             Some("either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, \
                   `fat`, or omitted");
-        pub const parse_cross_lang_lto: Option<&str> =
+        pub const parse_linker_plugin_lto: Option<&str> =
             Some("either a boolean (`yes`, `no`, `on`, `off`, etc), \
                   or the path to the linker plugin");
         pub const parse_merge_functions: Option<&str> =
@@ -821,7 +821,7 @@ macro_rules! options {
 
     #[allow(dead_code)]
     mod $mod_set {
-        use super::{$struct_name, Passes, Sanitizer, LtoCli, CrossLangLto};
+        use super::{$struct_name, Passes, Sanitizer, LtoCli, LinkerPluginLto};
         use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelroLevel};
         use std::path::PathBuf;
         use std::str::FromStr;
@@ -1037,22 +1037,22 @@ macro_rules! options {
             true
         }
 
-        fn parse_cross_lang_lto(slot: &mut CrossLangLto, v: Option<&str>) -> bool {
+        fn parse_linker_plugin_lto(slot: &mut LinkerPluginLto, v: Option<&str>) -> bool {
             if v.is_some() {
                 let mut bool_arg = None;
                 if parse_opt_bool(&mut bool_arg, v) {
                     *slot = if bool_arg.unwrap() {
-                        CrossLangLto::LinkerPluginAuto
+                        LinkerPluginLto::LinkerPluginAuto
                     } else {
-                        CrossLangLto::Disabled
+                        LinkerPluginLto::Disabled
                     };
                     return true
                 }
             }
 
             *slot = match v {
-                None => CrossLangLto::LinkerPluginAuto,
-                Some(path) => CrossLangLto::LinkerPlugin(PathBuf::from(path)),
+                None => LinkerPluginLto::LinkerPluginAuto,
+                Some(path) => LinkerPluginLto::LinkerPlugin(PathBuf::from(path)),
             };
             true
         }
@@ -1145,6 +1145,10 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
         "allow the linker to link its default libraries"),
     linker_flavor: Option<LinkerFlavor> = (None, parse_linker_flavor, [UNTRACKED],
                                            "Linker flavor"),
+    linker_plugin_lto: LinkerPluginLto = (LinkerPluginLto::Disabled,
+        parse_linker_plugin_lto, [TRACKED],
+        "generate build artifacts that are compatible with linker-based LTO."),
+
 }
 
 options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
@@ -1383,8 +1387,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         "make the current crate share its generic instantiations"),
     chalk: bool = (false, parse_bool, [TRACKED],
         "enable the experimental Chalk-based trait solving engine"),
-    cross_lang_lto: CrossLangLto = (CrossLangLto::Disabled, parse_cross_lang_lto, [TRACKED],
-        "generate build artifacts that are compatible with linker-based LTO."),
     no_parallel_llvm: bool = (false, parse_bool, [UNTRACKED],
         "don't run LLVM in parallel (while keeping codegen-units and ThinLTO)"),
     no_leak_check: bool = (false, parse_bool, [UNTRACKED],
@@ -2440,7 +2442,7 @@ mod dep_tracking {
     use std::path::PathBuf;
     use std::collections::hash_map::DefaultHasher;
     use super::{CrateType, DebugInfo, ErrorOutputType, OptLevel, OutputTypes,
-                Passes, Sanitizer, LtoCli, CrossLangLto};
+                Passes, Sanitizer, LtoCli, LinkerPluginLto};
     use syntax::feature_gate::UnstableFeatures;
     use rustc_target::spec::{MergeFunctions, PanicStrategy, RelroLevel, TargetTriple};
     use syntax::edition::Edition;
@@ -2507,7 +2509,7 @@ mod dep_tracking {
     impl_dep_tracking_hash_via_hash!(Option<Sanitizer>);
     impl_dep_tracking_hash_via_hash!(TargetTriple);
     impl_dep_tracking_hash_via_hash!(Edition);
-    impl_dep_tracking_hash_via_hash!(CrossLangLto);
+    impl_dep_tracking_hash_via_hash!(LinkerPluginLto);
 
     impl_dep_tracking_hash_for_sortable_vec_of!(String);
     impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf);
@@ -2572,7 +2574,7 @@ mod tests {
     use crate::lint;
     use crate::middle::cstore;
     use crate::session::config::{build_configuration, build_session_options_and_crate_config};
-    use crate::session::config::{LtoCli, CrossLangLto};
+    use crate::session::config::{LtoCli, LinkerPluginLto};
     use crate::session::build_session;
     use crate::session::search_paths::SearchPath;
     use std::collections::{BTreeMap, BTreeSet};
@@ -3105,6 +3107,10 @@ mod tests {
         opts = reference.clone();
         opts.cg.panic = Some(PanicStrategy::Abort);
         assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
+
+        opts = reference.clone();
+        opts.cg.linker_plugin_lto = LinkerPluginLto::LinkerPluginAuto;
+        assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
     }
 
     #[test]
@@ -3231,10 +3237,6 @@ mod tests {
         opts.debugging_opts.relro_level = Some(RelroLevel::Full);
         assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
 
-        opts = reference.clone();
-        opts.debugging_opts.cross_lang_lto = CrossLangLto::LinkerPluginAuto;
-        assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
-
         opts = reference.clone();
         opts.debugging_opts.merge_functions = Some(MergeFunctions::Disabled);
         assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 9f387e1eab1ef..e4b293558e592 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -1267,7 +1267,7 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
     // bitcode during ThinLTO. Therefore we disallow dynamic linking on MSVC
     // when compiling for LLD ThinLTO. This way we can validly just not generate
     // the `dllimport` attributes and `__imp_` symbols in that case.
-    if sess.opts.debugging_opts.cross_lang_lto.enabled() &&
+    if sess.opts.cg.linker_plugin_lto.enabled() &&
        sess.opts.cg.prefer_dynamic &&
        sess.target.target.options.is_like_msvc {
         sess.err("Linker plugin based LTO is not supported together with \
diff --git a/src/librustc_codegen_llvm/back/link.rs b/src/librustc_codegen_llvm/back/link.rs
index fc744201a332c..8bb985ecc25fa 100644
--- a/src/librustc_codegen_llvm/back/link.rs
+++ b/src/librustc_codegen_llvm/back/link.rs
@@ -857,7 +857,7 @@ fn link_args(cmd: &mut dyn Linker,
              codegen_results: &CodegenResults) {
 
     // Linker plugins should be specified early in the list of arguments
-    cmd.cross_lang_lto();
+    cmd.linker_plugin_lto();
 
     // The default library location, we need this to find the runtime.
     // The location of crates will be determined as needed.
@@ -1491,7 +1491,7 @@ fn are_upstream_rust_objects_already_included(sess: &Session) -> bool {
         Lto::Thin => {
             // If we defer LTO to the linker, we haven't run LTO ourselves, so
             // any upstream object files have not been copied yet.
-            !sess.opts.debugging_opts.cross_lang_lto.enabled()
+            !sess.opts.cg.linker_plugin_lto.enabled()
         }
         Lto::No |
         Lto::ThinLocal => false,
diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs
index 3e51078dc6436..b6b880c7ec4ac 100644
--- a/src/librustc_codegen_llvm/back/lto.rs
+++ b/src/librustc_codegen_llvm/back/lto.rs
@@ -159,7 +159,7 @@ pub(crate) fn run_thin(cgcx: &CodegenContext<LlvmCodegenBackend>,
     let symbol_white_list = symbol_white_list.iter()
                                              .map(|c| c.as_ptr())
                                              .collect::<Vec<_>>();
-    if cgcx.opts.debugging_opts.cross_lang_lto.enabled() {
+    if cgcx.opts.cg.linker_plugin_lto.enabled() {
         unreachable!("We should never reach this case if the LTO step \
                       is deferred to the linker");
     }
diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs
index 47637f3c5d705..e78715319727b 100644
--- a/src/librustc_codegen_llvm/back/write.rs
+++ b/src/librustc_codegen_llvm/back/write.rs
@@ -366,7 +366,7 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext<LlvmCodegenBackend>,
                 let opt_level = config.opt_level.map(|x| to_llvm_opt_settings(x).0)
                     .unwrap_or(llvm::CodeGenOptLevel::None);
                 let prepare_for_thin_lto = cgcx.lto == Lto::Thin || cgcx.lto == Lto::ThinLocal ||
-                    (cgcx.lto != Lto::Fat && cgcx.opts.debugging_opts.cross_lang_lto.enabled());
+                    (cgcx.lto != Lto::Fat && cgcx.opts.cg.linker_plugin_lto.enabled());
                 with_llvm_pmb(llmod, &config, opt_level, prepare_for_thin_lto, &mut |b| {
                     llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(b, fpm);
                     llvm::LLVMPassManagerBuilderPopulateModulePassManager(b, mpm);
diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs
index b7a9382c338bd..ca9e2c87be237 100644
--- a/src/librustc_codegen_llvm/consts.rs
+++ b/src/librustc_codegen_llvm/consts.rs
@@ -275,12 +275,12 @@ impl CodegenCx<'ll, 'tcx> {
                 self.use_dll_storage_attrs && !self.tcx.is_foreign_item(def_id) &&
                 // ThinLTO can't handle this workaround in all cases, so we don't
                 // emit the attrs. Instead we make them unnecessary by disallowing
-                // dynamic linking when cross-language LTO is enabled.
-                !self.tcx.sess.opts.debugging_opts.cross_lang_lto.enabled();
+                // dynamic linking when linker plugin based LTO is enabled.
+                !self.tcx.sess.opts.cg.linker_plugin_lto.enabled();
 
             // If this assertion triggers, there's something wrong with commandline
             // argument validation.
-            debug_assert!(!(self.tcx.sess.opts.debugging_opts.cross_lang_lto.enabled() &&
+            debug_assert!(!(self.tcx.sess.opts.cg.linker_plugin_lto.enabled() &&
                             self.tcx.sess.target.target.options.is_like_msvc &&
                             self.tcx.sess.opts.cg.prefer_dynamic));
 
diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs
index 249715a7b6e26..4b34bf704d588 100644
--- a/src/librustc_codegen_ssa/back/linker.rs
+++ b/src/librustc_codegen_ssa/back/linker.rs
@@ -13,7 +13,7 @@ use rustc::hir::def_id::{LOCAL_CRATE, CrateNum};
 use rustc::middle::dependency_format::Linkage;
 use rustc::session::Session;
 use rustc::session::config::{self, CrateType, OptLevel, DebugInfo,
-                             CrossLangLto, Lto};
+                             LinkerPluginLto, Lto};
 use rustc::ty::TyCtxt;
 use rustc_target::spec::{LinkerFlavor, LldFlavor};
 use serialize::{json, Encoder};
@@ -127,7 +127,7 @@ pub trait Linker {
     fn subsystem(&mut self, subsystem: &str);
     fn group_start(&mut self);
     fn group_end(&mut self);
-    fn cross_lang_lto(&mut self);
+    fn linker_plugin_lto(&mut self);
     // Should have been finalize(self), but we don't support self-by-value on trait objects (yet?).
     fn finalize(&mut self) -> Command;
 }
@@ -183,7 +183,7 @@ impl<'a> GccLinker<'a> {
         }
     }
 
-    fn push_cross_lang_lto_args(&mut self, plugin_path: Option<&OsStr>) {
+    fn push_linker_plugin_lto_args(&mut self, plugin_path: Option<&OsStr>) {
         if let Some(plugin_path) = plugin_path {
             let mut arg = OsString::from("-plugin=");
             arg.push(plugin_path);
@@ -454,16 +454,16 @@ impl<'a> Linker for GccLinker<'a> {
         }
     }
 
-    fn cross_lang_lto(&mut self) {
-        match self.sess.opts.debugging_opts.cross_lang_lto {
-            CrossLangLto::Disabled => {
+    fn linker_plugin_lto(&mut self) {
+        match self.sess.opts.cg.linker_plugin_lto {
+            LinkerPluginLto::Disabled => {
                 // Nothing to do
             }
-            CrossLangLto::LinkerPluginAuto => {
-                self.push_cross_lang_lto_args(None);
+            LinkerPluginLto::LinkerPluginAuto => {
+                self.push_linker_plugin_lto_args(None);
             }
-            CrossLangLto::LinkerPlugin(ref path) => {
-                self.push_cross_lang_lto_args(Some(path.as_os_str()));
+            LinkerPluginLto::LinkerPlugin(ref path) => {
+                self.push_linker_plugin_lto_args(Some(path.as_os_str()));
             }
         }
     }
@@ -697,7 +697,7 @@ impl<'a> Linker for MsvcLinker<'a> {
     fn group_start(&mut self) {}
     fn group_end(&mut self) {}
 
-    fn cross_lang_lto(&mut self) {
+    fn linker_plugin_lto(&mut self) {
         // Do nothing
     }
 }
@@ -865,7 +865,7 @@ impl<'a> Linker for EmLinker<'a> {
     fn group_start(&mut self) {}
     fn group_end(&mut self) {}
 
-    fn cross_lang_lto(&mut self) {
+    fn linker_plugin_lto(&mut self) {
         // Do nothing
     }
 }
@@ -1047,7 +1047,7 @@ impl<'a> Linker for WasmLd<'a> {
     fn group_start(&mut self) {}
     fn group_end(&mut self) {}
 
-    fn cross_lang_lto(&mut self) {
+    fn linker_plugin_lto(&mut self) {
         // Do nothing for now
     }
 }
diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs
index eeb191b09e249..81952c9c820b0 100644
--- a/src/librustc_codegen_ssa/back/write.rs
+++ b/src/librustc_codegen_ssa/back/write.rs
@@ -126,7 +126,7 @@ impl ModuleConfig {
         self.time_passes = sess.time_passes();
         self.inline_threshold = sess.opts.cg.inline_threshold;
         self.obj_is_bitcode = sess.target.target.options.obj_is_bitcode ||
-                              sess.opts.debugging_opts.cross_lang_lto.enabled();
+                              sess.opts.cg.linker_plugin_lto.enabled();
         let embed_bitcode = sess.target.target.options.embed_bitcode ||
                             sess.opts.debugging_opts.embed_bitcode;
         if embed_bitcode {
@@ -737,7 +737,7 @@ fn execute_optimize_work_item<B: ExtraBackendMethods>(
     // If the linker does LTO, we don't have to do it. Note that we
     // keep doing full LTO, if it is requested, as not to break the
     // assumption that the output will be a single module.
-    let linker_does_lto = cgcx.opts.debugging_opts.cross_lang_lto.enabled();
+    let linker_does_lto = cgcx.opts.cg.linker_plugin_lto.enabled();
 
     // When we're automatically doing ThinLTO for multi-codegen-unit
     // builds we don't actually want to LTO the allocator modules if
@@ -1883,7 +1883,7 @@ pub fn pre_lto_bitcode_filename(module_name: &str) -> String {
 fn msvc_imps_needed(tcx: TyCtxt) -> bool {
     // This should never be true (because it's not supported). If it is true,
     // something is wrong with commandline arg validation.
-    assert!(!(tcx.sess.opts.debugging_opts.cross_lang_lto.enabled() &&
+    assert!(!(tcx.sess.opts.cg.linker_plugin_lto.enabled() &&
               tcx.sess.target.target.options.is_like_msvc &&
               tcx.sess.opts.cg.prefer_dynamic));
 
@@ -1891,6 +1891,6 @@ fn msvc_imps_needed(tcx: TyCtxt) -> bool {
         tcx.sess.crate_types.borrow().iter().any(|ct| *ct == config::CrateType::Rlib) &&
     // ThinLTO can't handle this workaround in all cases, so we don't
     // emit the `__imp_` symbols. Instead we make them unnecessary by disallowing
-    // dynamic linking when cross-language LTO is enabled.
-    !tcx.sess.opts.debugging_opts.cross_lang_lto.enabled()
+    // dynamic linking when linker plugin LTO is enabled.
+    !tcx.sess.opts.cg.linker_plugin_lto.enabled()
 }
diff --git a/src/test/codegen/no-dllimport-w-cross-lang-lto.rs b/src/test/codegen/no-dllimport-w-cross-lang-lto.rs
index c1c1ef6ede2cb..33fc2bc1540d3 100644
--- a/src/test/codegen/no-dllimport-w-cross-lang-lto.rs
+++ b/src/test/codegen/no-dllimport-w-cross-lang-lto.rs
@@ -3,7 +3,7 @@
 
 // no-prefer-dynamic
 // only-msvc
-// compile-flags: -Z cross-lang-lto
+// compile-flags: -C linker-plugin-lto
 
 #![crate_type = "rlib"]
 
diff --git a/src/test/codegen/target-cpu-on-functions.rs b/src/test/codegen/target-cpu-on-functions.rs
index 5692dca1df5a2..3fdf6ab6d002f 100644
--- a/src/test/codegen/target-cpu-on-functions.rs
+++ b/src/test/codegen/target-cpu-on-functions.rs
@@ -3,7 +3,7 @@
 
 // no-prefer-dynamic
 // ignore-tidy-linelength
-// compile-flags: -C no-prepopulate-passes -C panic=abort -Z cross-lang-lto -Cpasses=name-anon-globals
+// compile-flags: -C no-prepopulate-passes -C panic=abort -C linker-plugin-lto -Cpasses=name-anon-globals
 
 #![crate_type = "staticlib"]
 
diff --git a/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile b/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile
index cf687070bc2ed..b3c5fb2d79647 100644
--- a/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile
+++ b/src/test/run-make-fulldeps/cross-lang-lto-clang/Makefile
@@ -8,7 +8,7 @@
 all: cpp-executable rust-executable
 
 cpp-executable:
-	$(RUSTC) -Zcross-lang-lto=on -o $(TMPDIR)/librustlib-xlto.a -Copt-level=2 -Ccodegen-units=1 ./rustlib.rs
+	$(RUSTC) -Clinker-plugin-lto=on -o $(TMPDIR)/librustlib-xlto.a -Copt-level=2 -Ccodegen-units=1 ./rustlib.rs
 	$(CLANG) -flto=thin -fuse-ld=lld -L $(TMPDIR) -lrustlib-xlto -o $(TMPDIR)/cmain ./cmain.c -O3
 	# Make sure we don't find a call instruction to the function we expect to
 	# always be inlined.
@@ -20,6 +20,6 @@ cpp-executable:
 rust-executable:
 	$(CLANG) ./clib.c -flto=thin -c -o $(TMPDIR)/clib.o -O2
 	(cd $(TMPDIR); $(AR) crus ./libxyz.a ./clib.o)
-	$(RUSTC) -Zcross-lang-lto=on -L$(TMPDIR) -Copt-level=2 -Clinker=$(CLANG) -Clink-arg=-fuse-ld=lld ./main.rs -o $(TMPDIR)/rsmain
+	$(RUSTC) -Clinker-plugin-lto=on -L$(TMPDIR) -Copt-level=2 -Clinker=$(CLANG) -Clink-arg=-fuse-ld=lld ./main.rs -o $(TMPDIR)/rsmain
 	llvm-objdump -d $(TMPDIR)/rsmain | $(CGREP) -e "call.*c_never_inlined"
 	llvm-objdump -d $(TMPDIR)/rsmain | $(CGREP) -v -e "call.*c_always_inlined"
diff --git a/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs/Makefile b/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs/Makefile
index 4f33b1c59e084..c9da06ff93f86 100644
--- a/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs/Makefile
+++ b/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs/Makefile
@@ -5,13 +5,13 @@
 ifndef IS_WINDOWS
 
 # This test makes sure that we don't loose upstream object files when compiling
-# staticlibs with -Zcross-lang-lto
+# staticlibs with -C linker-plugin-lto
 
 all: staticlib.rs upstream.rs
-	$(RUSTC) upstream.rs -Z cross-lang-lto -Ccodegen-units=1
+	$(RUSTC) upstream.rs -C linker-plugin-lto -Ccodegen-units=1
 
 	# Check No LTO
-	$(RUSTC) staticlib.rs -Z cross-lang-lto -Ccodegen-units=1 -L. -o $(TMPDIR)/staticlib.a
+	$(RUSTC) staticlib.rs -C linker-plugin-lto -Ccodegen-units=1 -L. -o $(TMPDIR)/staticlib.a
 	(cd $(TMPDIR); $(LD_LIB_PATH_ENVVAR)=$(REAL_LD_LIBRARY_PATH) llvm-ar x ./staticlib.a)
 	# Make sure the upstream object file was included
 	ls $(TMPDIR)/upstream.*.rcgu.o
@@ -20,8 +20,8 @@ all: staticlib.rs upstream.rs
 	rm $(TMPDIR)/*
 
 	# Check ThinLTO
-	$(RUSTC) upstream.rs -Z cross-lang-lto -Ccodegen-units=1 -Clto=thin
-	$(RUSTC) staticlib.rs -Z cross-lang-lto -Ccodegen-units=1 -Clto=thin -L. -o $(TMPDIR)/staticlib.a
+	$(RUSTC) upstream.rs -C linker-plugin-lto -Ccodegen-units=1 -Clto=thin
+	$(RUSTC) staticlib.rs -C linker-plugin-lto -Ccodegen-units=1 -Clto=thin -L. -o $(TMPDIR)/staticlib.a
 	(cd $(TMPDIR); $(LD_LIB_PATH_ENVVAR)=$(REAL_LD_LIBRARY_PATH) llvm-ar x ./staticlib.a)
 	ls $(TMPDIR)/upstream.*.rcgu.o
 
diff --git a/src/test/run-make-fulldeps/cross-lang-lto/Makefile b/src/test/run-make-fulldeps/cross-lang-lto/Makefile
index 57a19a0ccb037..43bd05a73592c 100644
--- a/src/test/run-make-fulldeps/cross-lang-lto/Makefile
+++ b/src/test/run-make-fulldeps/cross-lang-lto/Makefile
@@ -7,14 +7,14 @@ ifndef IS_WINDOWS
 
 # This test makes sure that the object files we generate are actually
 # LLVM bitcode files (as used by linker LTO plugins) when compiling with
-# -Z cross-lang-lto.
+# -Clinker-plugin-lto.
 
 # this only succeeds for bitcode files
 ASSERT_IS_BITCODE_OBJ=($(LD_LIB_PATH_ENVVAR)=$(REAL_LD_LIBRARY_PATH) llvm-bcanalyzer $(1))
 EXTRACT_OBJS=(cd $(TMPDIR); rm -f ./*.o; $(LD_LIB_PATH_ENVVAR)=$(REAL_LD_LIBRARY_PATH) llvm-ar x $(1))
 
-BUILD_LIB=$(RUSTC) lib.rs -Copt-level=2 -Z cross-lang-lto=on -Ccodegen-units=1
-BUILD_EXE=$(RUSTC) main.rs -Copt-level=2 -Z cross-lang-lto=on -Ccodegen-units=1 --emit=obj
+BUILD_LIB=$(RUSTC) lib.rs -Copt-level=2 -Clinker-plugin-lto -Ccodegen-units=1
+BUILD_EXE=$(RUSTC) main.rs -Copt-level=2 -Clinker-plugin-lto -Ccodegen-units=1 --emit=obj
 
 all: staticlib staticlib-fat-lto staticlib-thin-lto rlib exe cdylib rdylib
 

From 8b21a55b965aab6e5110fdb1d27c43d9212bd85f Mon Sep 17 00:00:00 2001
From: Andy Russell <arussell123@gmail.com>
Date: Mon, 11 Feb 2019 23:50:31 -0500
Subject: [PATCH 18/24] use Ubuntu keyserver for CloudABI ports

The Ubuntu keyserver is more reliable than the MIT PGP server, which is
prone to going down. This commit also explicitly uses port 80 on the
keyserver for reasons outlined in #57844.
---
 src/ci/docker/dist-various-2/build-cloudabi-toolchain.sh | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/src/ci/docker/dist-various-2/build-cloudabi-toolchain.sh b/src/ci/docker/dist-various-2/build-cloudabi-toolchain.sh
index 391f9b2fff889..3354a796c357e 100755
--- a/src/ci/docker/dist-various-2/build-cloudabi-toolchain.sh
+++ b/src/ci/docker/dist-various-2/build-cloudabi-toolchain.sh
@@ -32,9 +32,8 @@ ln -s ../lib/llvm-5.0/bin/lld /usr/bin/${target}-ld
 ln -s ../../${target} /usr/lib/llvm-5.0/${target}
 
 # Install the C++ runtime libraries from CloudABI Ports.
-echo deb https://nuxi.nl/distfiles/cloudabi-ports/debian/ cloudabi cloudabi > \
-    /etc/apt/sources.list.d/cloudabi.list
-curl 'https://pgp.mit.edu/pks/lookup?op=get&search=0x0DA51B8531344B15' | \
-    apt-key add -
+apt-key adv --batch --yes --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0DA51B8531344B15
+add-apt-repository -y 'deb https://nuxi.nl/distfiles/cloudabi-ports/debian/ cloudabi cloudabi'
+
 apt-get update
-apt-get install -y $(echo ${target} | sed -e s/_/-/g)-cxx-runtime
+apt-get install -y "${target//_/-}-cxx-runtime"

From 3733b3267dba89b442757c5ff5a791de5e36531b Mon Sep 17 00:00:00 2001
From: Michael Woerister <michaelwoerister@posteo>
Date: Tue, 12 Feb 2019 15:07:04 +0100
Subject: [PATCH 19/24] Add documentation about -Clinker-plugin-lto to rustc
 book.

---
 src/doc/rustc/src/SUMMARY.md           |   3 +-
 src/doc/rustc/src/linker-plugin-lto.md | 108 +++++++++++++++++++++++++
 2 files changed, 110 insertions(+), 1 deletion(-)
 create mode 100644 src/doc/rustc/src/linker-plugin-lto.md

diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index e4c0939fd4636..34708d1847f6b 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -13,4 +13,5 @@
 - [Targets](targets/index.md)
     - [Built-in Targets](targets/built-in.md)
     - [Custom Targets](targets/custom.md)
-- [Contributing to `rustc`](contributing.md)
\ No newline at end of file
+- [Linker-plugin based LTO](linker-plugin-lto.md)
+- [Contributing to `rustc`](contributing.md)
diff --git a/src/doc/rustc/src/linker-plugin-lto.md b/src/doc/rustc/src/linker-plugin-lto.md
new file mode 100644
index 0000000000000..73a2efcb33a75
--- /dev/null
+++ b/src/doc/rustc/src/linker-plugin-lto.md
@@ -0,0 +1,108 @@
+# Linker-plugin-LTO
+
+The `-C linker-plugin-lto` flag allows for deferring the LTO optimization
+to the actual linking step, which in turn allows for performing
+interprocedural optimizations across programming language boundaries if
+all the object files being linked were created by LLVM based toolchains.
+The prime example here would be linking Rust code together with
+Clang-compiled C/C++ code.
+
+## Usage
+
+There are two main cases how linker plugin based LTO can be used:
+
+ - compiling a Rust `staticlib` that is used as a C ABI dependency
+ - compiling a Rust binary where `rustc` invokes the linker
+
+In both cases the Rust code has to be compiled with `-C linker-plugin-lto` and
+the C/C++ code with `-flto` or `-flto=thin` so that object files are emitted
+as LLVM bitcode.
+
+### Rust `staticlib` as dependency in C/C++ program
+
+In this case the Rust compiler just has to make sure that the object files in
+the `staticlib` are in the right format. For linking, a linker with the
+LLVM plugin must be used (e.g. LLD).
+
+Using `rustc` directly:
+
+```bash
+# Compile the Rust staticlib
+rustc --crate-type=staticlib -Clinker-plugin-lto -Copt-level=2 ./lib.rs
+# Compile the C code with `-flto=thin`
+clang -c -O2 -flto=thin -o main.o ./main.c
+# Link everything, making sure that we use an appropriate linker
+clang -flto=thin -fuse-ld=lld -L . -l"name-of-your-rust-lib" -o main -O2 ./cmain.o
+```
+
+Using `cargo`:
+
+```bash
+# Compile the Rust staticlib
+RUSTFLAGS="-Clinker-plugin-lto" cargo build --release
+# Compile the C code with `-flto=thin`
+clang -c -O2 -flto=thin -o main.o ./main.c
+# Link everything, making sure that we use an appropriate linker
+clang -flto=thin -fuse-ld=lld -L . -l"name-of-your-rust-lib" -o main -O2 ./cmain.o
+```
+
+### C/C++ code as a dependency in Rust
+
+In this case the linker will be invoked by `rustc`. We again have to make sure
+that an appropriate linker is used.
+
+Using `rustc` directly:
+
+```bash
+# Compile C code with `-flto`
+clang ./clib.c -flto=thin -c -o ./clib.o -O2
+# Create a static library from the C code
+ar crus ./libxyz.a ./clib.o
+
+# Invoke `rustc` with the additional arguments
+rustc -Clinker-plugin-lto -L. -Copt-level=2 -Clinker=clang -Clink-arg=-fuse-ld=lld ./main.rs
+```
+
+Using `cargo` directly:
+
+```bash
+# Compile C code with `-flto`
+clang ./clib.c -flto=thin -c -o ./clib.o -O2
+# Create a static library from the C code
+ar crus ./libxyz.a ./clib.o
+
+# Set the linking arguments via RUSTFLAGS
+RUSTFLAGS="-Clinker-plugin-lto -Clinker=clang -Clink-arg=-fuse-ld=lld" cargo build --release
+```
+
+### Explicitly specifying the linker plugin to be used by `rustc`
+
+If one wants to use a linker other than LLD, the LLVM linker plugin has to be
+specified explicitly. Otherwise the linker cannot read the object files. The
+path to the plugin is passed as an argument to the `-Clinker-plugin-lto`
+option:
+
+```bash
+rustc -Clinker-plugin-lto="/path/to/LLVMgold.so" -L. -Copt-level=2 ./main.rs
+```
+
+
+## Toolchain Compatibility
+
+In order for this kind of LTO to work, the LLVM linker plugin must be able to
+handle the LLVM bitcode produced by both `rustc` and `clang`.
+
+Best results are achieved by using a `rustc` and `clang` that are based on the
+exact same version of LLVM. One can use `rustc -vV` in order to view the LLVM
+used by a given `rustc` version. Note that the version number given
+here is only an approximation as Rust sometimes uses unstable revisions of
+LLVM. However, the approximation is usually reliable.
+
+The following table shows known good combinations of toolchain versions.
+
+|           | Clang 7   | Clang 8   |
+|-----------|-----------|-----------|
+| Rust 1.34 |     ✗     |     ✓     |
+| Rust 1.35 |     ✗     |    ✓(?)   |
+
+Note that the compatibility policy for this feature might change in the future.

From 1431c216feaca4a551c26778e2e6309eb00fbe2b Mon Sep 17 00:00:00 2001
From: gnzlbg <gonzalobg88@gmail.com>
Date: Tue, 12 Feb 2019 16:11:27 +0100
Subject: [PATCH 20/24] Remove some dead code from libcore

These macros are not required to glue the `core_arch` crate anymore.
---
 src/libcore/lib.rs | 14 --------------
 1 file changed, 14 deletions(-)

diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 78f1c3c0dffa5..6e0fc9f1ffeec 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -226,20 +226,6 @@ mod unit;
 // `core_arch` depends on libcore, but the contents of this module are
 // set up in such a way that directly pulling it here works such that the
 // crate uses the this crate as its libcore.
-#[allow(unused_macros)]
-macro_rules! test_v16 { ($item:item) => {}; }
-#[allow(unused_macros)]
-macro_rules! test_v32 { ($item:item) => {}; }
-#[allow(unused_macros)]
-macro_rules! test_v64 { ($item:item) => {}; }
-#[allow(unused_macros)]
-macro_rules! test_v128 { ($item:item) => {}; }
-#[allow(unused_macros)]
-macro_rules! test_v256 { ($item:item) => {}; }
-#[allow(unused_macros)]
-macro_rules! test_v512 { ($item:item) => {}; }
-#[allow(unused_macros)]
-macro_rules! vector_impl { ($([$f:ident, $($args:tt)*]),*) => { $($f!($($args)*);)* } }
 #[path = "../stdsimd/crates/core_arch/src/mod.rs"]
 #[allow(missing_docs, missing_debug_implementations, dead_code, unused_imports)]
 #[unstable(feature = "stdsimd", issue = "48556")]

From 3216c7656afbada6af3cbf77ef5236a7153f58e8 Mon Sep 17 00:00:00 2001
From: Taiki Endo <te316e89@gmail.com>
Date: Fri, 8 Feb 2019 00:56:05 +0900
Subject: [PATCH 21/24] Rename rustc_errors dependency in rust 2018 crates

---
 src/librustc/Cargo.toml                                   | 2 +-
 src/librustc/dep_graph/graph.rs                           | 2 +-
 src/librustc/hir/lowering.rs                              | 2 +-
 src/librustc/hir/mod.rs                                   | 2 +-
 src/librustc/infer/error_reporting/mod.rs                 | 2 +-
 src/librustc/infer/error_reporting/need_type_info.rs      | 2 +-
 .../nice_region_error/named_anon_conflict.rs              | 2 +-
 .../nice_region_error/placeholder_error.rs                | 2 +-
 .../nice_region_error/static_impl_trait.rs                | 2 +-
 src/librustc/infer/error_reporting/note.rs                | 2 +-
 src/librustc/infer/mod.rs                                 | 2 +-
 src/librustc/lib.rs                                       | 2 --
 src/librustc/lint/builtin.rs                              | 2 +-
 src/librustc/lint/context.rs                              | 2 +-
 src/librustc/lint/levels.rs                               | 2 +-
 src/librustc/lint/mod.rs                                  | 2 +-
 src/librustc/middle/lib_features.rs                       | 2 +-
 src/librustc/middle/liveness.rs                           | 2 +-
 src/librustc/middle/resolve_lifetime.rs                   | 2 +-
 src/librustc/mir/interpret/error.rs                       | 2 +-
 src/librustc/session/config.rs                            | 3 +--
 src/librustc/session/mod.rs                               | 4 ++--
 src/librustc/traits/coherence.rs                          | 2 +-
 src/librustc/traits/error_reporting.rs                    | 2 +-
 src/librustc/traits/select.rs                             | 2 +-
 src/librustc/ty/context.rs                                | 4 ++--
 src/librustc/ty/error.rs                                  | 2 +-
 src/librustc/ty/query/mod.rs                              | 2 +-
 src/librustc/ty/query/on_disk_cache.rs                    | 2 +-
 src/librustc/ty/query/plumbing.rs                         | 8 ++++----
 src/librustc_resolve/Cargo.toml                           | 2 +-
 src/librustc_resolve/build_reduced_graph.rs               | 2 +-
 src/librustc_resolve/lib.rs                               | 2 --
 src/librustc_resolve/macros.rs                            | 2 +-
 src/libsyntax/Cargo.toml                                  | 2 +-
 src/libsyntax/attr/builtin.rs                             | 2 +-
 src/libsyntax/config.rs                                   | 2 +-
 src/libsyntax/diagnostics/plugin.rs                       | 2 +-
 src/libsyntax/ext/base.rs                                 | 2 +-
 src/libsyntax/ext/expand.rs                               | 2 +-
 src/libsyntax/ext/tt/macro_parser.rs                      | 2 +-
 src/libsyntax/ext/tt/macro_rules.rs                       | 4 ++--
 src/libsyntax/feature_gate.rs                             | 2 +-
 src/libsyntax/json.rs                                     | 8 ++++----
 src/libsyntax/lib.rs                                      | 6 +++---
 src/libsyntax/parse/lexer/mod.rs                          | 3 +--
 src/libsyntax/parse/lexer/unicode_chars.rs                | 2 +-
 src/libsyntax/parse/mod.rs                                | 2 +-
 src/libsyntax/parse/parser.rs                             | 2 +-
 src/libsyntax/show_span.rs                                | 1 -
 src/libsyntax/source_map.rs                               | 2 +-
 src/libsyntax/test.rs                                     | 2 +-
 src/libsyntax/test_snippet.rs                             | 4 ++--
 src/libsyntax_ext/Cargo.toml                              | 2 +-
 src/libsyntax_ext/asm.rs                                  | 2 +-
 src/libsyntax_ext/assert.rs                               | 2 +-
 src/libsyntax_ext/cfg.rs                                  | 2 +-
 src/libsyntax_ext/deriving/custom.rs                      | 2 +-
 src/libsyntax_ext/format.rs                               | 4 ++--
 src/libsyntax_ext/global_asm.rs                           | 2 +-
 src/libsyntax_ext/lib.rs                                  | 2 --
 src/libsyntax_ext/proc_macro_decls.rs                     | 1 -
 src/libsyntax_ext/proc_macro_impl.rs                      | 2 +-
 src/libsyntax_ext/proc_macro_server.rs                    | 2 +-
 64 files changed, 72 insertions(+), 82 deletions(-)

diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml
index c9a04f4c6834d..cb9eb32f8d21f 100644
--- a/src/librustc/Cargo.toml
+++ b/src/librustc/Cargo.toml
@@ -25,7 +25,7 @@ rustc-rayon-core = "0.1.1"
 rustc_apfloat = { path = "../librustc_apfloat" }
 rustc_target = { path = "../librustc_target" }
 rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_errors = { path = "../librustc_errors" }
+errors = { path = "../librustc_errors", package = "rustc_errors" }
 serialize = { path = "../libserialize" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs
index e8c1cd36064e1..feaff39719b09 100644
--- a/src/librustc/dep_graph/graph.rs
+++ b/src/librustc/dep_graph/graph.rs
@@ -1,4 +1,4 @@
-use crate::errors::{Diagnostic, DiagnosticBuilder};
+use errors::{Diagnostic, DiagnosticBuilder};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 43c756def88be..1a825c44add1e 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -31,7 +31,7 @@
 //! in the HIR, especially for multiple identifiers.
 
 use crate::dep_graph::DepGraph;
-use crate::errors::Applicability;
+use errors::Applicability;
 use crate::hir::{self, ParamName};
 use crate::hir::HirVec;
 use crate::hir::map::{DefKey, DefPathData, Definitions};
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 3e7dd1432e1e3..e454a4502d484 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -10,7 +10,7 @@ pub use self::PrimTy::*;
 pub use self::UnOp::*;
 pub use self::UnsafeSource::*;
 
-use crate::errors::FatalError;
+use errors::FatalError;
 use crate::hir::def::Def;
 use crate::hir::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX};
 use crate::util::nodemap::{NodeMap, FxHashSet};
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 1c23438a3b48a..f408cc9e3e417 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -50,7 +50,7 @@ use super::region_constraints::GenericKind;
 use super::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TypeTrace, ValuePairs};
 use crate::infer::{self, SuppressRegionErrors};
 
-use crate::errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
+use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
 use crate::hir;
 use crate::hir::def_id::DefId;
 use crate::hir::Node;
diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs
index fac498bd6dd78..7c8146a1a5943 100644
--- a/src/librustc/infer/error_reporting/need_type_info.rs
+++ b/src/librustc/infer/error_reporting/need_type_info.rs
@@ -5,7 +5,7 @@ use crate::infer::type_variable::TypeVariableOrigin;
 use crate::ty::{self, Ty, Infer, TyVar};
 use syntax::source_map::CompilerDesugaringKind;
 use syntax_pos::Span;
-use crate::errors::DiagnosticBuilder;
+use errors::DiagnosticBuilder;
 
 struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
     infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
diff --git a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs
index d66bb274b34ce..b10af400f2b6c 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs
@@ -3,7 +3,7 @@
 use crate::infer::error_reporting::nice_region_error::NiceRegionError;
 use crate::ty;
 use crate::util::common::ErrorReported;
-use crate::errors::Applicability;
+use errors::Applicability;
 
 impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
     /// When given a `ConcreteFailure` for a function with arguments containing a named region and
diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs
index 6893a1fb168b8..843fa8b0182e2 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs
@@ -1,4 +1,4 @@
-use crate::errors::DiagnosticBuilder;
+use errors::DiagnosticBuilder;
 use crate::hir::def_id::DefId;
 use crate::infer::error_reporting::nice_region_error::NiceRegionError;
 use crate::infer::lexical_region_resolve::RegionResolutionError;
diff --git a/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs
index 3f0297952278a..23acaeb31f8d4 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs
@@ -4,7 +4,7 @@ use crate::infer::error_reporting::nice_region_error::NiceRegionError;
 use crate::infer::lexical_region_resolve::RegionResolutionError;
 use crate::ty::{BoundRegion, FreeRegion, RegionKind};
 use crate::util::common::ErrorReported;
-use crate::errors::Applicability;
+use errors::Applicability;
 
 impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
     /// Print the error message for lifetime errors when the return type is a static impl Trait.
diff --git a/src/librustc/infer/error_reporting/note.rs b/src/librustc/infer/error_reporting/note.rs
index 6c481e8c0c114..c05c6567bbefa 100644
--- a/src/librustc/infer/error_reporting/note.rs
+++ b/src/librustc/infer/error_reporting/note.rs
@@ -2,7 +2,7 @@ use crate::infer::{self, InferCtxt, SubregionOrigin};
 use crate::middle::region;
 use crate::ty::{self, Region};
 use crate::ty::error::TypeError;
-use crate::errors::DiagnosticBuilder;
+use errors::DiagnosticBuilder;
 
 impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     pub(super) fn note_region_origin(&self,
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index dabe1755b0bb6..706aae88d15ca 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -8,7 +8,7 @@ pub use self::ValuePairs::*;
 pub use crate::ty::IntVarValue;
 
 use arena::SyncDroplessArena;
-use crate::errors::DiagnosticBuilder;
+use errors::DiagnosticBuilder;
 use crate::hir::def_id::DefId;
 use crate::infer::canonical::{Canonical, CanonicalVarValues};
 use crate::middle::free_region::RegionRelations;
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index be1475564778a..bfe59eda06e6f 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -153,8 +153,6 @@ mod rustc {
     pub use crate::lint;
 }
 
-use rustc_errors as errors;
-
 // FIXME(#27438): right now the unit tests of librustc don't refer to any actual
 //                functions generated in librustc_data_structures (all
 //                references are through generic functions), but statics are
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index cb31441ca47e1..e6546617e2d98 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -4,7 +4,7 @@
 //! compiler code, rather than using their own custom pass. Those
 //! lints are all available in `rustc_lint::builtin`.
 
-use crate::errors::{Applicability, DiagnosticBuilder};
+use errors::{Applicability, DiagnosticBuilder};
 use crate::lint::{LintPass, LateLintPass, LintArray};
 use crate::session::Session;
 use syntax::ast;
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 27ead805d5dbd..a2b34a705f780 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -34,7 +34,7 @@ use std::default::Default as StdDefault;
 use syntax::ast;
 use syntax::edition;
 use syntax_pos::{MultiSpan, Span, symbol::{LocalInternedString, Symbol}};
-use crate::errors::DiagnosticBuilder;
+use errors::DiagnosticBuilder;
 use crate::hir;
 use crate::hir::def_id::LOCAL_CRATE;
 use crate::hir::intravisit as hir_visit;
diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs
index 62bd54de7c929..5d2da64986843 100644
--- a/src/librustc/lint/levels.rs
+++ b/src/librustc/lint/levels.rs
@@ -1,6 +1,6 @@
 use std::cmp;
 
-use crate::errors::{Applicability, DiagnosticBuilder};
+use errors::{Applicability, DiagnosticBuilder};
 use crate::hir::HirId;
 use crate::ich::StableHashingContext;
 use crate::lint::builtin;
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 8952ae98e597e..7913afe1a4b12 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -23,7 +23,7 @@ pub use self::LintSource::*;
 
 use rustc_data_structures::sync::{self, Lrc};
 
-use crate::errors::{DiagnosticBuilder, DiagnosticId};
+use errors::{DiagnosticBuilder, DiagnosticId};
 use crate::hir::def_id::{CrateNum, LOCAL_CRATE};
 use crate::hir::intravisit;
 use crate::hir;
diff --git a/src/librustc/middle/lib_features.rs b/src/librustc/middle/lib_features.rs
index 45095d9bc986b..c56c98ac00872 100644
--- a/src/librustc/middle/lib_features.rs
+++ b/src/librustc/middle/lib_features.rs
@@ -10,7 +10,7 @@ use syntax::ast::{Attribute, MetaItem, MetaItemKind};
 use syntax_pos::Span;
 use crate::hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_data_structures::fx::{FxHashSet, FxHashMap};
-use crate::errors::DiagnosticId;
+use errors::DiagnosticId;
 
 pub struct LibFeatures {
     // A map from feature to stabilisation version.
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 4eb7b918dd8be..68f62bd96c23b 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -102,7 +102,7 @@ use crate::hir::Node;
 use crate::ty::{self, TyCtxt};
 use crate::ty::query::Providers;
 use crate::lint;
-use crate::errors::Applicability;
+use errors::Applicability;
 use crate::util::nodemap::{NodeMap, HirIdMap, HirIdSet};
 
 use std::collections::{BTreeMap, VecDeque};
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index f187928e0d900..0e56c1664adf1 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -11,7 +11,7 @@ use crate::hir::map::Map;
 use crate::hir::{GenericArg, GenericParam, ItemLocalId, LifetimeName, Node, ParamName};
 use crate::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt};
 
-use crate::errors::{Applicability, DiagnosticBuilder};
+use errors::{Applicability, DiagnosticBuilder};
 use crate::rustc::lint;
 use rustc_data_structures::sync::Lrc;
 use crate::session::Session;
diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs
index 870a51f95df1c..b0bee80e40b54 100644
--- a/src/librustc/mir/interpret/error.rs
+++ b/src/librustc/mir/interpret/error.rs
@@ -11,7 +11,7 @@ use super::{RawConst, Pointer, InboundsCheck, ScalarMaybeUndef};
 use backtrace::Backtrace;
 
 use crate::ty::query::TyCtxtAt;
-use crate::errors::DiagnosticBuilder;
+use errors::DiagnosticBuilder;
 
 use syntax_pos::{Pos, Span};
 use syntax::ast;
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 1a92f2c0f7aa1..aa5bc6e48a8ea 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -19,7 +19,7 @@ use syntax::parse;
 use syntax::symbol::Symbol;
 use syntax::feature_gate::UnstableFeatures;
 
-use crate::errors::{ColorConfig, FatalError, Handler};
+use errors::{ColorConfig, FatalError, Handler};
 
 use getopts;
 use std::collections::{BTreeMap, BTreeSet};
@@ -2567,7 +2567,6 @@ mod dep_tracking {
 
 #[cfg(test)]
 mod tests {
-    use crate::errors;
     use getopts;
     use crate::lint;
     use crate::middle::cstore;
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 9f387e1eab1ef..3df76bdfa60ca 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -21,8 +21,8 @@ use rustc_data_structures::sync::{
     Ordering::SeqCst,
 };
 
-use crate::errors::{self, DiagnosticBuilder, DiagnosticId, Applicability};
-use crate::errors::emitter::{Emitter, EmitterWriter};
+use errors::{DiagnosticBuilder, DiagnosticId, Applicability};
+use errors::emitter::{Emitter, EmitterWriter};
 use syntax::ast::{self, NodeId};
 use syntax::edition::Edition;
 use syntax::feature_gate::{self, AttributeType};
diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs
index 4fe7a1507f737..a1ada9fe17f21 100644
--- a/src/librustc/traits/coherence.rs
+++ b/src/librustc/traits/coherence.rs
@@ -39,7 +39,7 @@ pub struct OverlapResult<'tcx> {
     pub involves_placeholder: bool,
 }
 
-pub fn add_placeholder_note(err: &mut crate::errors::DiagnosticBuilder<'_>) {
+pub fn add_placeholder_note(err: &mut errors::DiagnosticBuilder<'_>) {
     err.note(&format!(
         "this behavior recently changed as a result of a bug fix; \
          see rust-lang/rust#56105 for details"
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index c17adaf1f9f98..600311e6c34b8 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -17,7 +17,7 @@ use super::{
     Overflow,
 };
 
-use crate::errors::{Applicability, DiagnosticBuilder};
+use errors::{Applicability, DiagnosticBuilder};
 use crate::hir;
 use crate::hir::Node;
 use crate::hir::def_id::DefId;
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 1e4cd145e1760..d4b656f2322a6 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -103,7 +103,7 @@ impl IntercrateAmbiguityCause {
     /// See #23980 for details.
     pub fn add_intercrate_ambiguity_hint<'a, 'tcx>(
         &self,
-        err: &mut crate::errors::DiagnosticBuilder<'_>,
+        err: &mut errors::DiagnosticBuilder<'_>,
     ) {
         err.note(&self.intercrate_ambiguity_hint());
     }
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 11211c91c5479..0010eb98c6b35 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -2,7 +2,7 @@
 
 use crate::dep_graph::DepGraph;
 use crate::dep_graph::{self, DepNode, DepConstructor};
-use crate::errors::DiagnosticBuilder;
+use errors::DiagnosticBuilder;
 use crate::session::Session;
 use crate::session::config::{BorrowckMode, OutputFilenames};
 use crate::session::config::CrateType;
@@ -1819,7 +1819,7 @@ pub mod tls {
     use std::ptr;
     use syntax_pos;
     use crate::ty::query;
-    use crate::errors::{Diagnostic, TRACK_DIAGNOSTICS};
+    use errors::{Diagnostic, TRACK_DIAGNOSTICS};
     use rustc_data_structures::OnDrop;
     use rustc_data_structures::sync::{self, Lrc, Lock};
     use rustc_data_structures::thin_vec::ThinVec;
diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index d0c9677ea6ecb..e3e0ce147741f 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -4,7 +4,7 @@ use std::borrow::Cow;
 use std::fmt;
 use rustc_target::spec::abi;
 use syntax::ast;
-use crate::errors::{Applicability, DiagnosticBuilder};
+use errors::{Applicability, DiagnosticBuilder};
 use syntax_pos::Span;
 
 use crate::hir;
diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs
index d002b99f385a3..cc43dbd779efc 100644
--- a/src/librustc/ty/query/mod.rs
+++ b/src/librustc/ty/query/mod.rs
@@ -1,5 +1,5 @@
 use crate::dep_graph::{self, DepConstructor, DepNode};
-use crate::errors::DiagnosticBuilder;
+use errors::DiagnosticBuilder;
 use crate::hir::def_id::{CrateNum, DefId, DefIndex};
 use crate::hir::def::{Def, Export};
 use crate::hir::{self, TraitCandidate, ItemLocalId, CodegenFnAttrs};
diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
index 9c9bc0f6aa11c..8b6e1aae74f9a 100644
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ b/src/librustc/ty/query/on_disk_cache.rs
@@ -1,5 +1,5 @@
 use crate::dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
-use crate::errors::Diagnostic;
+use errors::Diagnostic;
 use crate::hir;
 use crate::hir::def_id::{CrateNum, DefIndex, DefId, LocalDefId, LOCAL_CRATE};
 use crate::hir::map::definitions::DefPathHash;
diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs
index f63fbd79825db..6b1fa359037fb 100644
--- a/src/librustc/ty/query/plumbing.rs
+++ b/src/librustc/ty/query/plumbing.rs
@@ -3,10 +3,10 @@
 //! provider, manage the caches, and so forth.
 
 use crate::dep_graph::{DepNodeIndex, DepNode, DepKind, SerializedDepNodeIndex};
-use crate::errors::DiagnosticBuilder;
-use crate::errors::Level;
-use crate::errors::Diagnostic;
-use crate::errors::FatalError;
+use errors::DiagnosticBuilder;
+use errors::Level;
+use errors::Diagnostic;
+use errors::FatalError;
 use crate::ty::tls;
 use crate::ty::{TyCtxt};
 use crate::ty::query::Query;
diff --git a/src/librustc_resolve/Cargo.toml b/src/librustc_resolve/Cargo.toml
index 0ce82f2ce521b..836b4ad38ca88 100644
--- a/src/librustc_resolve/Cargo.toml
+++ b/src/librustc_resolve/Cargo.toml
@@ -16,7 +16,7 @@ log = "0.4"
 syntax = { path = "../libsyntax" }
 rustc = { path = "../librustc" }
 arena = { path = "../libarena" }
-rustc_errors = { path = "../librustc_errors" }
+errors = { path = "../librustc_errors", package = "rustc_errors" }
 syntax_pos = { path = "../libsyntax_pos" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_metadata = { path = "../librustc_metadata" }
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 750eb35a98854..c1942c47dbbe9 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -22,7 +22,7 @@ use std::cell::Cell;
 use std::ptr;
 use rustc_data_structures::sync::Lrc;
 
-use crate::errors::Applicability;
+use errors::Applicability;
 
 use syntax::ast::{Name, Ident};
 use syntax::attr;
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index ad73b30ae3fd9..1a3eb82a48efa 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -10,8 +10,6 @@
 
 #![deny(rust_2018_idioms)]
 
-use rustc_errors as errors;
-
 pub use rustc::hir::def::{Namespace, PerNS};
 
 use GenericParameters::*;
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index c8c0847a28eac..74ee45abdb890 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -27,7 +27,7 @@ use syntax::symbol::{Symbol, keywords};
 use syntax::visit::Visitor;
 use syntax::util::lev_distance::find_best_match_for_name;
 use syntax_pos::{Span, DUMMY_SP};
-use crate::errors::Applicability;
+use errors::Applicability;
 
 use std::cell::Cell;
 use std::{mem, ptr};
diff --git a/src/libsyntax/Cargo.toml b/src/libsyntax/Cargo.toml
index f1e60ba78b753..4a0bb0302ffbc 100644
--- a/src/libsyntax/Cargo.toml
+++ b/src/libsyntax/Cargo.toml
@@ -15,7 +15,7 @@ serialize = { path = "../libserialize" }
 log = "0.4"
 scoped-tls = "0.1"
 syntax_pos = { path = "../libsyntax_pos" }
-rustc_errors = { path = "../librustc_errors" }
+errors = { path = "../librustc_errors", package = "rustc_errors" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_target = { path = "../librustc_target" }
 smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs
index 6f7761b54fc29..bb44706c1e378 100644
--- a/src/libsyntax/attr/builtin.rs
+++ b/src/libsyntax/attr/builtin.rs
@@ -1,7 +1,7 @@
 //! Parsing and validation of builtin attributes
 
 use crate::ast::{self, Attribute, MetaItem, Name, NestedMetaItemKind};
-use crate::errors::{Applicability, Handler};
+use errors::{Applicability, Handler};
 use crate::feature_gate::{Features, GatedCfg};
 use crate::parse::ParseSess;
 
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index bfc4457f0547f..9565d02a9c2c2 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -9,7 +9,7 @@ use crate::feature_gate::{
 use crate::attr;
 use crate::ast;
 use crate::edition::Edition;
-use crate::errors::Applicability;
+use errors::Applicability;
 use crate::mut_visit::*;
 use crate::parse::{token, ParseSess};
 use crate::ptr::P;
diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs
index e79378d93bd1d..21024eb41ef50 100644
--- a/src/libsyntax/diagnostics/plugin.rs
+++ b/src/libsyntax/diagnostics/plugin.rs
@@ -15,7 +15,7 @@ use syntax_pos::Span;
 
 use crate::diagnostics::metadata::output_metadata;
 
-pub use crate::errors::*;
+pub use errors::*;
 
 // Maximum width of any line in an extended error description (inclusive).
 const MAX_DESCRIPTION_WIDTH: usize = 80;
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index f7225810aca74..5c0f391d271b0 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -4,7 +4,7 @@ use crate::ast::{self, Attribute, Name, PatKind, MetaItem};
 use crate::attr::HasAttrs;
 use crate::source_map::{SourceMap, Spanned, respan};
 use crate::edition::Edition;
-use crate::errors::{DiagnosticBuilder, DiagnosticId};
+use errors::{DiagnosticBuilder, DiagnosticId};
 use crate::ext::expand::{self, AstFragment, Invocation};
 use crate::ext::hygiene::{self, Mark, SyntaxContext, Transparency};
 use crate::mut_visit::{self, MutVisitor};
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 60359531b7f63..c007377add0b3 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -3,7 +3,7 @@ use crate::ast::{MacStmtStyle, StmtKind, ItemKind};
 use crate::attr::{self, HasAttrs};
 use crate::source_map::{ExpnInfo, MacroBang, MacroAttribute, dummy_spanned, respan};
 use crate::config::StripUnconfigured;
-use crate::errors::{Applicability, FatalError};
+use errors::{Applicability, FatalError};
 use crate::ext::base::*;
 use crate::ext::derive::{add_derived_markers, collect_derives};
 use crate::ext::hygiene::{self, Mark, SyntaxContext};
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index a9000b89fb48e..b69a3b428bbe1 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -75,7 +75,7 @@ pub use ParseResult::*;
 use TokenTreeOrTokenTreeSlice::*;
 
 use crate::ast::Ident;
-use crate::errors::FatalError;
+use errors::FatalError;
 use crate::ext::tt::quoted::{self, TokenTree};
 use crate::parse::{Directory, ParseSess};
 use crate::parse::parser::{Parser, PathStyle};
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index cc5531c401046..a3bdb3ba2286a 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -1,6 +1,6 @@
 use crate::{ast, attr};
 use crate::edition::Edition;
-use crate::errors::FatalError;
+use errors::FatalError;
 use crate::ext::base::{DummyResult, ExtCtxt, MacResult, SyntaxExtension};
 use crate::ext::base::{NormalTT, TTMacroExpander};
 use crate::ext::expand::{AstFragment, AstFragmentKind};
@@ -25,7 +25,7 @@ use std::borrow::Cow;
 use std::collections::hash_map::Entry;
 
 use rustc_data_structures::sync::Lrc;
-use crate::errors::Applicability;
+use errors::Applicability;
 
 const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \
     `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, \
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 4d24c7bfb4038..8f1188d2aaa68 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -20,7 +20,7 @@ use crate::attr;
 use crate::early_buffered_lints::BufferedEarlyLintId;
 use crate::source_map::Spanned;
 use crate::edition::{ALL_EDITIONS, Edition};
-use crate::errors::{DiagnosticBuilder, Handler};
+use errors::{DiagnosticBuilder, Handler};
 use crate::visit::{self, FnKind, Visitor};
 use crate::parse::ParseSess;
 use crate::symbol::Symbol;
diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs
index 2953b35298eab..94b25111d9d18 100644
--- a/src/libsyntax/json.rs
+++ b/src/libsyntax/json.rs
@@ -10,10 +10,10 @@
 // FIXME: spec the JSON output properly.
 
 use crate::source_map::{SourceMap, FilePathMapping};
-use crate::errors::registry::Registry;
-use crate::errors::{DiagnosticBuilder, SubDiagnostic, CodeSuggestion, SourceMapper};
-use crate::errors::{DiagnosticId, Applicability};
-use crate::errors::emitter::{Emitter, EmitterWriter};
+use errors::registry::Registry;
+use errors::{DiagnosticBuilder, SubDiagnostic, CodeSuggestion, SourceMapper};
+use errors::{DiagnosticId, Applicability};
+use errors::emitter::{Emitter, EmitterWriter};
 
 use syntax_pos::{self, MacroBacktrace, Span, SpanLabel, MultiSpan};
 use rustc_data_structures::sync::{self, Lrc};
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index c844f9e2a91ee..e0557147f9a01 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -25,7 +25,7 @@
 #[allow(unused_extern_crates)]
 extern crate serialize as rustc_serialize; // used by deriving
 
-pub use rustc_errors as errors;
+pub use errors;
 use rustc_data_structures::sync::Lock;
 use rustc_data_structures::bit_set::GrowableBitSet;
 pub use rustc_data_structures::thin_vec::ThinVec;
@@ -38,7 +38,7 @@ use ast::AttrId;
 macro_rules! panictry {
     ($e:expr) => ({
         use std::result::Result::{Ok, Err};
-        use crate::errors::FatalError;
+        use errors::FatalError;
         match $e {
             Ok(e) => e,
             Err(mut e) => {
@@ -53,7 +53,7 @@ macro_rules! panictry {
 macro_rules! panictry_buffer {
     ($handler:expr, $e:expr) => ({
         use std::result::Result::{Ok, Err};
-        use crate::errors::{FatalError, DiagnosticBuilder};
+        use errors::{FatalError, DiagnosticBuilder};
         match $e {
             Ok(e) => e,
             Err(errs) => {
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index d3fc1c03634ea..1634cbfc15629 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -1,6 +1,6 @@
 use crate::ast::{self, Ident};
 use crate::source_map::{SourceMap, FilePathMapping};
-use crate::errors::{Applicability, FatalError, Diagnostic, DiagnosticBuilder};
+use errors::{Applicability, FatalError, Diagnostic, DiagnosticBuilder};
 use crate::parse::{token, ParseSess};
 use crate::symbol::{Symbol, keywords};
 
@@ -1882,7 +1882,6 @@ mod tests {
     use crate::ast::{Ident, CrateConfig};
     use crate::symbol::Symbol;
     use crate::source_map::SourceMap;
-    use crate::errors;
     use crate::feature_gate::UnstableFeatures;
     use crate::parse::token;
     use crate::diagnostics::plugin::ErrorMap;
diff --git a/src/libsyntax/parse/lexer/unicode_chars.rs b/src/libsyntax/parse/lexer/unicode_chars.rs
index 75862178169ea..7da4284c0e4aa 100644
--- a/src/libsyntax/parse/lexer/unicode_chars.rs
+++ b/src/libsyntax/parse/lexer/unicode_chars.rs
@@ -2,7 +2,7 @@
 // http://www.unicode.org/Public/security/10.0.0/confusables.txt
 
 use syntax_pos::{Span, NO_EXPANSION};
-use crate::errors::{Applicability, DiagnosticBuilder};
+use errors::{Applicability, DiagnosticBuilder};
 use super::StringReader;
 
 const UNICODE_ARRAY: &[(char, &str, char)] = &[
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 317d693320786..1ac3d8ec78166 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -3,7 +3,7 @@
 use crate::ast::{self, CrateConfig, NodeId};
 use crate::early_buffered_lints::{BufferedEarlyLint, BufferedEarlyLintId};
 use crate::source_map::{SourceMap, FilePathMapping};
-use crate::errors::{FatalError, Level, Handler, ColorConfig, Diagnostic, DiagnosticBuilder};
+use errors::{FatalError, Level, Handler, ColorConfig, Diagnostic, DiagnosticBuilder};
 use crate::feature_gate::UnstableFeatures;
 use crate::parse::parser::Parser;
 use crate::symbol::Symbol;
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 69d6407d506fb..8db8c253bad45 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -33,7 +33,7 @@ use crate::ast::{RangeEnd, RangeSyntax};
 use crate::{ast, attr};
 use crate::ext::base::DummyResult;
 use crate::source_map::{self, SourceMap, Spanned, respan};
-use crate::errors::{self, Applicability, DiagnosticBuilder, DiagnosticId};
+use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
 use crate::parse::{self, SeqSep, classify, token};
 use crate::parse::lexer::{TokenAndSpan, UnmatchedBrace};
 use crate::parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
diff --git a/src/libsyntax/show_span.rs b/src/libsyntax/show_span.rs
index 2c32771266e7d..5e0cf9eea78b8 100644
--- a/src/libsyntax/show_span.rs
+++ b/src/libsyntax/show_span.rs
@@ -6,7 +6,6 @@
 use std::str::FromStr;
 
 use crate::ast;
-use crate::errors;
 use crate::visit;
 use crate::visit::Visitor;
 
diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs
index 552a3d30261eb..d33415eb68a13 100644
--- a/src/libsyntax/source_map.rs
+++ b/src/libsyntax/source_map.rs
@@ -24,7 +24,7 @@ use std::fs;
 use std::io;
 use log::debug;
 
-use crate::errors::SourceMapper;
+use errors::SourceMapper;
 
 /// Return the span itself if it doesn't come from a macro expansion,
 /// otherwise return the call site span up to the `enclosing_sp` by
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs
index f45bf034ba2f8..6506546b3b2ef 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -16,7 +16,7 @@ use syntax_pos::{self, DUMMY_SP, NO_EXPANSION, Span, SourceFile, BytePos};
 
 use crate::attr::{self, HasAttrs};
 use crate::source_map::{self, SourceMap, ExpnInfo, MacroAttribute, dummy_spanned, respan};
-use crate::errors;
+use errors;
 use crate::config;
 use crate::entry::{self, EntryPointType};
 use crate::ext::base::{ExtCtxt, Resolver};
diff --git a/src/libsyntax/test_snippet.rs b/src/libsyntax/test_snippet.rs
index add4d2bead139..e9ea39b83d4cb 100644
--- a/src/libsyntax/test_snippet.rs
+++ b/src/libsyntax/test_snippet.rs
@@ -1,6 +1,6 @@
 use crate::source_map::{SourceMap, FilePathMapping};
-use crate::errors::Handler;
-use crate::errors::emitter::EmitterWriter;
+use errors::Handler;
+use errors::emitter::EmitterWriter;
 use crate::with_globals;
 
 use std::io;
diff --git a/src/libsyntax_ext/Cargo.toml b/src/libsyntax_ext/Cargo.toml
index c22b55b8c13a0..773f0948a8a10 100644
--- a/src/libsyntax_ext/Cargo.toml
+++ b/src/libsyntax_ext/Cargo.toml
@@ -11,7 +11,7 @@ crate-type = ["dylib"]
 
 [dependencies]
 fmt_macros = { path = "../libfmt_macros" }
-rustc_errors = { path = "../librustc_errors" }
+errors = { path = "../librustc_errors", package = "rustc_errors" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
 rustc_data_structures = { path = "../librustc_data_structures" }
diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs
index ebcdceea7c5a9..8edd0e1ae3884 100644
--- a/src/libsyntax_ext/asm.rs
+++ b/src/libsyntax_ext/asm.rs
@@ -4,7 +4,7 @@ use State::*;
 
 use rustc_data_structures::thin_vec::ThinVec;
 
-use crate::errors::DiagnosticBuilder;
+use errors::DiagnosticBuilder;
 
 use syntax::ast;
 use syntax::ext::base::{self, *};
diff --git a/src/libsyntax_ext/assert.rs b/src/libsyntax_ext/assert.rs
index 984ef26f5ab8b..d2c397e0eccb5 100644
--- a/src/libsyntax_ext/assert.rs
+++ b/src/libsyntax_ext/assert.rs
@@ -1,4 +1,4 @@
-use crate::errors::DiagnosticBuilder;
+use errors::DiagnosticBuilder;
 
 use syntax::ast::{self, *};
 use syntax::source_map::Spanned;
diff --git a/src/libsyntax_ext/cfg.rs b/src/libsyntax_ext/cfg.rs
index e2104550878ec..090d730289d26 100644
--- a/src/libsyntax_ext/cfg.rs
+++ b/src/libsyntax_ext/cfg.rs
@@ -2,7 +2,7 @@
 /// a literal `true` or `false` based on whether the given cfg matches the
 /// current compilation environment.
 
-use crate::errors::DiagnosticBuilder;
+use errors::DiagnosticBuilder;
 
 use syntax::ast;
 use syntax::ext::base::{self, *};
diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs
index 7d9b8402cac3f..81fcdc4be2b3d 100644
--- a/src/libsyntax_ext/deriving/custom.rs
+++ b/src/libsyntax_ext/deriving/custom.rs
@@ -1,4 +1,4 @@
-use crate::errors::FatalError;
+use errors::FatalError;
 use crate::proc_macro_impl::EXEC_STRATEGY;
 use crate::proc_macro_server;
 
diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index 1b17fc0d040a5..a27630a714c28 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -3,8 +3,8 @@ use Position::*;
 
 use fmt_macros as parse;
 
-use crate::errors::DiagnosticBuilder;
-use crate::errors::Applicability;
+use errors::DiagnosticBuilder;
+use errors::Applicability;
 
 use syntax::ast;
 use syntax::ext::base::{self, *};
diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs
index 14dbd9300232b..2baf530aedae7 100644
--- a/src/libsyntax_ext/global_asm.rs
+++ b/src/libsyntax_ext/global_asm.rs
@@ -8,7 +8,7 @@
 /// LLVM's `module asm "some assembly here"`. All of LLVM's caveats
 /// therefore apply.
 
-use crate::errors::DiagnosticBuilder;
+use errors::DiagnosticBuilder;
 
 use syntax::ast;
 use syntax::source_map::respan;
diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs
index 05c8084a51ed2..69f9e2c5eb0ec 100644
--- a/src/libsyntax_ext/lib.rs
+++ b/src/libsyntax_ext/lib.rs
@@ -17,8 +17,6 @@
 
 extern crate proc_macro;
 
-use rustc_errors as errors;
-
 mod diagnostics;
 
 mod asm;
diff --git a/src/libsyntax_ext/proc_macro_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs
index 5730081ce018a..d8f8decef39b1 100644
--- a/src/libsyntax_ext/proc_macro_decls.rs
+++ b/src/libsyntax_ext/proc_macro_decls.rs
@@ -1,7 +1,6 @@
 use std::mem;
 
 use crate::deriving;
-use crate::errors;
 
 use syntax::ast::{self, Ident};
 use syntax::attr;
diff --git a/src/libsyntax_ext/proc_macro_impl.rs b/src/libsyntax_ext/proc_macro_impl.rs
index 88e20e3dc7c9e..03290df0c72ae 100644
--- a/src/libsyntax_ext/proc_macro_impl.rs
+++ b/src/libsyntax_ext/proc_macro_impl.rs
@@ -1,4 +1,4 @@
-use crate::errors::FatalError;
+use errors::FatalError;
 use crate::proc_macro_server;
 
 use syntax::source_map::Span;
diff --git a/src/libsyntax_ext/proc_macro_server.rs b/src/libsyntax_ext/proc_macro_server.rs
index 2158cfc089bdd..fd82dac5ab6d8 100644
--- a/src/libsyntax_ext/proc_macro_server.rs
+++ b/src/libsyntax_ext/proc_macro_server.rs
@@ -1,4 +1,4 @@
-use crate::errors::{self, Diagnostic, DiagnosticBuilder};
+use errors::{Diagnostic, DiagnosticBuilder};
 
 use std::panic;
 

From c360ba285c5a74ce659811a0c72fb7bf32ec0b85 Mon Sep 17 00:00:00 2001
From: Taiki Endo <te316e89@gmail.com>
Date: Sat, 9 Feb 2019 11:24:02 +0900
Subject: [PATCH 22/24] Cleanup imports

---
 src/librustc/hir/lowering.rs              | 10 +++++-----
 src/librustc/hir/mod.rs                   |  2 +-
 src/librustc/infer/error_reporting/mod.rs |  6 +++---
 src/librustc/infer/mod.rs                 | 19 ++++++++++---------
 src/librustc/lint/builtin.rs              |  2 +-
 src/librustc/lint/levels.rs               |  6 +++---
 src/librustc/lint/mod.rs                  |  8 ++++----
 src/librustc/middle/lib_features.rs       |  2 +-
 src/librustc/middle/liveness.rs           |  2 +-
 src/librustc/middle/resolve_lifetime.rs   |  6 +++---
 src/librustc/traits/error_reporting.rs    |  6 +++---
 src/librustc/ty/context.rs                |  2 +-
 src/librustc/ty/query/mod.rs              |  4 ++--
 src/librustc/ty/query/on_disk_cache.rs    | 19 ++++++++++---------
 src/librustc/ty/query/plumbing.rs         |  8 ++++----
 src/libsyntax/attr/builtin.rs             |  2 +-
 src/libsyntax/config.rs                   |  2 +-
 src/libsyntax/ext/base.rs                 |  2 +-
 src/libsyntax/ext/expand.rs               |  2 +-
 src/libsyntax/ext/tt/macro_parser.rs      |  4 ++--
 src/libsyntax/ext/tt/macro_rules.rs       |  2 +-
 src/libsyntax/feature_gate.rs             |  2 +-
 src/libsyntax/json.rs                     |  3 ++-
 src/libsyntax/parse/lexer/mod.rs          |  4 ++--
 src/libsyntax/parse/mod.rs                |  2 +-
 src/libsyntax/parse/parser.rs             |  4 ++--
 src/libsyntax/test.rs                     |  3 +--
 src/libsyntax/test_snippet.rs             |  3 ++-
 src/libsyntax_ext/deriving/custom.rs      |  2 +-
 src/libsyntax_ext/proc_macro_impl.rs      |  2 +-
 30 files changed, 72 insertions(+), 69 deletions(-)

diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 1a825c44add1e..bdf781761cc94 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -31,7 +31,6 @@
 //! in the HIR, especially for multiple identifiers.
 
 use crate::dep_graph::DepGraph;
-use errors::Applicability;
 use crate::hir::{self, ParamName};
 use crate::hir::HirVec;
 use crate::hir::map::{DefKey, DefPathData, Definitions};
@@ -41,14 +40,15 @@ use crate::hir::GenericArg;
 use crate::lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
                     ELIDED_LIFETIMES_IN_PATHS};
 use crate::middle::cstore::CrateStore;
-use rustc_data_structures::fx::FxHashSet;
-use rustc_data_structures::indexed_vec::IndexVec;
-use rustc_data_structures::thin_vec::ThinVec;
-use rustc_data_structures::sync::Lrc;
 use crate::session::Session;
 use crate::session::config::nightly_options;
 use crate::util::common::FN_OUTPUT_NAME;
 use crate::util::nodemap::{DefIdMap, NodeMap};
+use errors::Applicability;
+use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::indexed_vec::IndexVec;
+use rustc_data_structures::thin_vec::ThinVec;
+use rustc_data_structures::sync::Lrc;
 
 use std::collections::{BTreeSet, BTreeMap};
 use std::fmt::Debug;
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index e454a4502d484..7238551d22e07 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -10,12 +10,12 @@ pub use self::PrimTy::*;
 pub use self::UnOp::*;
 pub use self::UnsafeSource::*;
 
-use errors::FatalError;
 use crate::hir::def::Def;
 use crate::hir::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX};
 use crate::util::nodemap::{NodeMap, FxHashSet};
 use crate::mir::mono::Linkage;
 
+use errors::FatalError;
 use syntax_pos::{Span, DUMMY_SP, symbol::InternedString};
 use syntax::source_map::Spanned;
 use rustc_target::spec::abi::Abi;
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index f408cc9e3e417..93c0246474936 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -50,16 +50,16 @@ use super::region_constraints::GenericKind;
 use super::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TypeTrace, ValuePairs};
 use crate::infer::{self, SuppressRegionErrors};
 
-use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
 use crate::hir;
 use crate::hir::def_id::DefId;
 use crate::hir::Node;
 use crate::middle::region;
-use std::{cmp, fmt};
-use syntax_pos::{Pos, Span};
 use crate::traits::{ObligationCause, ObligationCauseCode};
 use crate::ty::error::TypeError;
 use crate::ty::{self, subst::Subst, Region, Ty, TyCtxt, TyKind, TypeFoldable};
+use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
+use std::{cmp, fmt};
+use syntax_pos::{Pos, Span};
 
 mod note;
 
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index 706aae88d15ca..3b822e01a4264 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -7,21 +7,12 @@ pub use self::SubregionOrigin::*;
 pub use self::ValuePairs::*;
 pub use crate::ty::IntVarValue;
 
-use arena::SyncDroplessArena;
-use errors::DiagnosticBuilder;
 use crate::hir::def_id::DefId;
 use crate::infer::canonical::{Canonical, CanonicalVarValues};
 use crate::middle::free_region::RegionRelations;
 use crate::middle::lang_items;
 use crate::middle::region;
-use rustc_data_structures::unify as ut;
 use crate::session::config::BorrowckMode;
-use std::cell::{Cell, Ref, RefCell, RefMut};
-use std::collections::BTreeMap;
-use std::fmt;
-use syntax::ast;
-use syntax_pos::symbol::InternedString;
-use syntax_pos::{self, Span};
 use crate::traits::{self, ObligationCause, PredicateObligations, TraitEngine};
 use crate::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
 use crate::ty::fold::TypeFoldable;
@@ -31,6 +22,16 @@ use crate::ty::{self, GenericParamDefKind, Ty, TyCtxt, CtxtInterners};
 use crate::ty::{FloatVid, IntVid, TyVid};
 use crate::util::nodemap::FxHashMap;
 
+use arena::SyncDroplessArena;
+use errors::DiagnosticBuilder;
+use rustc_data_structures::unify as ut;
+use std::cell::{Cell, Ref, RefCell, RefMut};
+use std::collections::BTreeMap;
+use std::fmt;
+use syntax::ast;
+use syntax_pos::symbol::InternedString;
+use syntax_pos::Span;
+
 use self::combine::CombineFields;
 use self::lexical_region_resolve::LexicalRegionResolutions;
 use self::outlives::env::OutlivesEnvironment;
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index e6546617e2d98..6f10b0e2c0e67 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -4,9 +4,9 @@
 //! compiler code, rather than using their own custom pass. Those
 //! lints are all available in `rustc_lint::builtin`.
 
-use errors::{Applicability, DiagnosticBuilder};
 use crate::lint::{LintPass, LateLintPass, LintArray};
 use crate::session::Session;
+use errors::{Applicability, DiagnosticBuilder};
 use syntax::ast;
 use syntax::source_map::Span;
 
diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs
index 5d2da64986843..924aa3fde0a08 100644
--- a/src/librustc/lint/levels.rs
+++ b/src/librustc/lint/levels.rs
@@ -1,20 +1,20 @@
 use std::cmp;
 
-use errors::{Applicability, DiagnosticBuilder};
 use crate::hir::HirId;
 use crate::ich::StableHashingContext;
 use crate::lint::builtin;
 use crate::lint::context::CheckLintNameResult;
 use crate::lint::{self, Lint, LintId, Level, LintSource};
+use crate::session::Session;
+use crate::util::nodemap::FxHashMap;
+use errors::{Applicability, DiagnosticBuilder};
 use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
                                            StableHasher, StableHasherResult};
-use crate::session::Session;
 use syntax::ast;
 use syntax::attr;
 use syntax::feature_gate;
 use syntax::source_map::MultiSpan;
 use syntax::symbol::Symbol;
-use crate::util::nodemap::FxHashMap;
 
 pub struct LintLevelSets {
     list: Vec<LintSet>,
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 7913afe1a4b12..479f93b19bcdb 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -23,13 +23,16 @@ pub use self::LintSource::*;
 
 use rustc_data_structures::sync::{self, Lrc};
 
-use errors::{DiagnosticBuilder, DiagnosticId};
 use crate::hir::def_id::{CrateNum, LOCAL_CRATE};
 use crate::hir::intravisit;
 use crate::hir;
 use crate::lint::builtin::{BuiltinLintDiagnostics, DUPLICATE_MATCHER_BINDING_NAME};
 use crate::lint::builtin::parser::{QUESTION_MARK_MACRO_SEP, ILL_FORMED_ATTRIBUTE_INPUT};
 use crate::session::{Session, DiagnosticMessageId};
+use crate::ty::TyCtxt;
+use crate::ty::query::Providers;
+use crate::util::nodemap::NodeMap;
+use errors::{DiagnosticBuilder, DiagnosticId};
 use std::{hash, ptr};
 use syntax::ast;
 use syntax::source_map::{MultiSpan, ExpnFormat};
@@ -37,9 +40,6 @@ use syntax::early_buffered_lints::BufferedEarlyLintId;
 use syntax::edition::Edition;
 use syntax::symbol::Symbol;
 use syntax_pos::Span;
-use crate::ty::TyCtxt;
-use crate::ty::query::Providers;
-use crate::util::nodemap::NodeMap;
 
 pub use crate::lint::context::{LateContext, EarlyContext, LintContext, LintStore,
                         check_crate, check_ast_crate, CheckLintNameResult,
diff --git a/src/librustc/middle/lib_features.rs b/src/librustc/middle/lib_features.rs
index c56c98ac00872..331343e052dea 100644
--- a/src/librustc/middle/lib_features.rs
+++ b/src/librustc/middle/lib_features.rs
@@ -5,10 +5,10 @@
 // (unlike lang features), which means we need to collect them instead.
 
 use crate::ty::TyCtxt;
+use crate::hir::intravisit::{self, NestedVisitorMap, Visitor};
 use syntax::symbol::Symbol;
 use syntax::ast::{Attribute, MetaItem, MetaItemKind};
 use syntax_pos::Span;
-use crate::hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_data_structures::fx::{FxHashSet, FxHashMap};
 use errors::DiagnosticId;
 
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 68f62bd96c23b..6ff364e37d57e 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -102,9 +102,9 @@ use crate::hir::Node;
 use crate::ty::{self, TyCtxt};
 use crate::ty::query::Providers;
 use crate::lint;
-use errors::Applicability;
 use crate::util::nodemap::{NodeMap, HirIdMap, HirIdSet};
 
+use errors::Applicability;
 use std::collections::{BTreeMap, VecDeque};
 use std::{fmt, u32};
 use std::io::prelude::*;
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 0e56c1664adf1..1a2f72cfa0254 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -11,10 +11,11 @@ use crate::hir::map::Map;
 use crate::hir::{GenericArg, GenericParam, ItemLocalId, LifetimeName, Node, ParamName};
 use crate::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt};
 
-use errors::{Applicability, DiagnosticBuilder};
 use crate::rustc::lint;
-use rustc_data_structures::sync::Lrc;
 use crate::session::Session;
+use crate::util::nodemap::{DefIdMap, FxHashMap, FxHashSet, NodeMap, NodeSet};
+use errors::{Applicability, DiagnosticBuilder};
+use rustc_data_structures::sync::Lrc;
 use std::borrow::Cow;
 use std::cell::Cell;
 use std::mem::replace;
@@ -23,7 +24,6 @@ use syntax::attr;
 use syntax::ptr::P;
 use syntax::symbol::keywords;
 use syntax_pos::Span;
-use crate::util::nodemap::{DefIdMap, FxHashMap, FxHashSet, NodeMap, NodeSet};
 
 use crate::hir::intravisit::{self, NestedVisitorMap, Visitor};
 use crate::hir::{self, GenericParamKind, LifetimeParamKind};
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 600311e6c34b8..55cb6e9baeccc 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -17,14 +17,11 @@ use super::{
     Overflow,
 };
 
-use errors::{Applicability, DiagnosticBuilder};
 use crate::hir;
 use crate::hir::Node;
 use crate::hir::def_id::DefId;
 use crate::infer::{self, InferCtxt};
 use crate::infer::type_variable::TypeVariableOrigin;
-use std::fmt;
-use syntax::ast;
 use crate::session::DiagnosticMessageId;
 use crate::ty::{self, AdtKind, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
 use crate::ty::GenericParamDefKind;
@@ -35,6 +32,9 @@ use crate::ty::subst::Subst;
 use crate::ty::SubtypePredicate;
 use crate::util::nodemap::{FxHashMap, FxHashSet};
 
+use errors::{Applicability, DiagnosticBuilder};
+use std::fmt;
+use syntax::ast;
 use syntax_pos::{DUMMY_SP, Span, ExpnInfo, ExpnFormat};
 
 impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 0010eb98c6b35..17b607328cc7d 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -2,7 +2,6 @@
 
 use crate::dep_graph::DepGraph;
 use crate::dep_graph::{self, DepNode, DepConstructor};
-use errors::DiagnosticBuilder;
 use crate::session::Session;
 use crate::session::config::{BorrowckMode, OutputFilenames};
 use crate::session::config::CrateType;
@@ -43,6 +42,7 @@ use crate::ty::{BoundVar, BindingMode};
 use crate::ty::CanonicalPolyFnSig;
 use crate::util::nodemap::{DefIdMap, DefIdSet, ItemLocalMap};
 use crate::util::nodemap::{FxHashMap, FxHashSet};
+use errors::DiagnosticBuilder;
 use rustc_data_structures::interner::HashInterner;
 use smallvec::SmallVec;
 use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs
index cc43dbd779efc..6aa810dcb2f05 100644
--- a/src/librustc/ty/query/mod.rs
+++ b/src/librustc/ty/query/mod.rs
@@ -1,9 +1,7 @@
 use crate::dep_graph::{self, DepConstructor, DepNode};
-use errors::DiagnosticBuilder;
 use crate::hir::def_id::{CrateNum, DefId, DefIndex};
 use crate::hir::def::{Def, Export};
 use crate::hir::{self, TraitCandidate, ItemLocalId, CodegenFnAttrs};
-use rustc_data_structures::svh::Svh;
 use crate::infer::canonical::{self, Canonical};
 use crate::lint;
 use crate::middle::borrowck::BorrowCheckResult;
@@ -44,6 +42,8 @@ use crate::util::common::{ErrorReported};
 use crate::util::profiling::ProfileCategory::*;
 use crate::session::Session;
 
+use errors::DiagnosticBuilder;
+use rustc_data_structures::svh::Svh;
 use rustc_data_structures::bit_set::BitSet;
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
index 8b6e1aae74f9a..8656c21ce1064 100644
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ b/src/librustc/ty/query/on_disk_cache.rs
@@ -1,28 +1,29 @@
 use crate::dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
-use errors::Diagnostic;
 use crate::hir;
 use crate::hir::def_id::{CrateNum, DefIndex, DefId, LocalDefId, LOCAL_CRATE};
 use crate::hir::map::definitions::DefPathHash;
 use crate::ich::{CachingSourceMapView, Fingerprint};
 use crate::mir::{self, interpret};
 use crate::mir::interpret::{AllocDecodingSession, AllocDecodingState};
-use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::thin_vec::ThinVec;
-use rustc_data_structures::sync::{Lrc, Lock, HashMapExt, Once};
-use rustc_data_structures::indexed_vec::{IndexVec, Idx};
 use crate::rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque,
                       SpecializedDecoder, SpecializedEncoder,
                       UseSpecializedDecodable, UseSpecializedEncodable};
 use crate::session::{CrateDisambiguator, Session};
+use crate::ty;
+use crate::ty::codec::{self as ty_codec, TyDecoder, TyEncoder};
+use crate::ty::context::TyCtxt;
+use crate::util::common::time;
+
+use errors::Diagnostic;
+use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::thin_vec::ThinVec;
+use rustc_data_structures::sync::{Lrc, Lock, HashMapExt, Once};
+use rustc_data_structures::indexed_vec::{IndexVec, Idx};
 use std::mem;
 use syntax::ast::NodeId;
 use syntax::source_map::{SourceMap, StableSourceFileId};
 use syntax_pos::{BytePos, Span, DUMMY_SP, SourceFile};
 use syntax_pos::hygiene::{Mark, SyntaxContext, ExpnInfo};
-use crate::ty;
-use crate::ty::codec::{self as ty_codec, TyDecoder, TyEncoder};
-use crate::ty::context::TyCtxt;
-use crate::util::common::time;
 
 const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE;
 
diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs
index 6b1fa359037fb..49c6093fb7d65 100644
--- a/src/librustc/ty/query/plumbing.rs
+++ b/src/librustc/ty/query/plumbing.rs
@@ -3,10 +3,6 @@
 //! provider, manage the caches, and so forth.
 
 use crate::dep_graph::{DepNodeIndex, DepNode, DepKind, SerializedDepNodeIndex};
-use errors::DiagnosticBuilder;
-use errors::Level;
-use errors::Diagnostic;
-use errors::FatalError;
 use crate::ty::tls;
 use crate::ty::{TyCtxt};
 use crate::ty::query::Query;
@@ -16,6 +12,10 @@ use crate::ty::item_path;
 
 use crate::util::common::{profq_msg, ProfileQueriesMsg, QueryMsg};
 
+use errors::DiagnosticBuilder;
+use errors::Level;
+use errors::Diagnostic;
+use errors::FatalError;
 use rustc_data_structures::fx::{FxHashMap};
 use rustc_data_structures::sync::{Lrc, Lock};
 use rustc_data_structures::thin_vec::ThinVec;
diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs
index bb44706c1e378..7afe84d11dcb0 100644
--- a/src/libsyntax/attr/builtin.rs
+++ b/src/libsyntax/attr/builtin.rs
@@ -1,10 +1,10 @@
 //! Parsing and validation of builtin attributes
 
 use crate::ast::{self, Attribute, MetaItem, Name, NestedMetaItemKind};
-use errors::{Applicability, Handler};
 use crate::feature_gate::{Features, GatedCfg};
 use crate::parse::ParseSess;
 
+use errors::{Applicability, Handler};
 use syntax_pos::{symbol::Symbol, Span};
 
 use super::{list_contains_name, mark_used, MetaItemKind};
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index 9565d02a9c2c2..66e9fa042dfa1 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -9,12 +9,12 @@ use crate::feature_gate::{
 use crate::attr;
 use crate::ast;
 use crate::edition::Edition;
-use errors::Applicability;
 use crate::mut_visit::*;
 use crate::parse::{token, ParseSess};
 use crate::ptr::P;
 use crate::util::map_in_place::MapInPlace;
 
+use errors::Applicability;
 use smallvec::SmallVec;
 
 /// A folder that strips out items that do not belong in the current configuration.
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 5c0f391d271b0..12caf8e23de14 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -4,7 +4,6 @@ use crate::ast::{self, Attribute, Name, PatKind, MetaItem};
 use crate::attr::HasAttrs;
 use crate::source_map::{SourceMap, Spanned, respan};
 use crate::edition::Edition;
-use errors::{DiagnosticBuilder, DiagnosticId};
 use crate::ext::expand::{self, AstFragment, Invocation};
 use crate::ext::hygiene::{self, Mark, SyntaxContext, Transparency};
 use crate::mut_visit::{self, MutVisitor};
@@ -15,6 +14,7 @@ use crate::symbol::{keywords, Ident, Symbol};
 use crate::ThinVec;
 use crate::tokenstream::{self, TokenStream};
 
+use errors::{DiagnosticBuilder, DiagnosticId};
 use smallvec::{smallvec, SmallVec};
 use syntax_pos::{Span, MultiSpan, DUMMY_SP};
 
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index c007377add0b3..359db7325158b 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -3,7 +3,6 @@ use crate::ast::{MacStmtStyle, StmtKind, ItemKind};
 use crate::attr::{self, HasAttrs};
 use crate::source_map::{ExpnInfo, MacroBang, MacroAttribute, dummy_spanned, respan};
 use crate::config::StripUnconfigured;
-use errors::{Applicability, FatalError};
 use crate::ext::base::*;
 use crate::ext::derive::{add_derived_markers, collect_derives};
 use crate::ext::hygiene::{self, Mark, SyntaxContext};
@@ -20,6 +19,7 @@ use crate::tokenstream::{TokenStream, TokenTree};
 use crate::visit::{self, Visitor};
 use crate::util::map_in_place::MapInPlace;
 
+use errors::{Applicability, FatalError};
 use smallvec::{smallvec, SmallVec};
 use syntax_pos::{Span, DUMMY_SP, FileName};
 use syntax_pos::hygiene::ExpnFormat;
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index b69a3b428bbe1..fe9b5a068c45d 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -75,7 +75,6 @@ pub use ParseResult::*;
 use TokenTreeOrTokenTreeSlice::*;
 
 use crate::ast::Ident;
-use errors::FatalError;
 use crate::ext::tt::quoted::{self, TokenTree};
 use crate::parse::{Directory, ParseSess};
 use crate::parse::parser::{Parser, PathStyle};
@@ -84,8 +83,9 @@ use crate::print::pprust;
 use crate::symbol::keywords;
 use crate::tokenstream::{DelimSpan, TokenStream};
 
+use errors::FatalError;
 use smallvec::{smallvec, SmallVec};
-use syntax_pos::{self, Span};
+use syntax_pos::Span;
 
 use rustc_data_structures::fx::FxHashMap;
 use std::collections::hash_map::Entry::{Occupied, Vacant};
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index a3bdb3ba2286a..6f5a4eabb0215 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -1,6 +1,5 @@
 use crate::{ast, attr};
 use crate::edition::Edition;
-use errors::FatalError;
 use crate::ext::base::{DummyResult, ExtCtxt, MacResult, SyntaxExtension};
 use crate::ext::base::{NormalTT, TTMacroExpander};
 use crate::ext::expand::{AstFragment, AstFragmentKind};
@@ -17,6 +16,7 @@ use crate::parse::token::Token::*;
 use crate::symbol::Symbol;
 use crate::tokenstream::{DelimSpan, TokenStream, TokenTree};
 
+use errors::FatalError;
 use syntax_pos::{Span, DUMMY_SP, symbol::Ident};
 use log::debug;
 
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 8f1188d2aaa68..14183a496a9fa 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -20,11 +20,11 @@ use crate::attr;
 use crate::early_buffered_lints::BufferedEarlyLintId;
 use crate::source_map::Spanned;
 use crate::edition::{ALL_EDITIONS, Edition};
-use errors::{DiagnosticBuilder, Handler};
 use crate::visit::{self, FnKind, Visitor};
 use crate::parse::ParseSess;
 use crate::symbol::Symbol;
 
+use errors::{DiagnosticBuilder, Handler};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_target::spec::abi::Abi;
 use syntax_pos::{Span, DUMMY_SP};
diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs
index 94b25111d9d18..09f77fd33dbd0 100644
--- a/src/libsyntax/json.rs
+++ b/src/libsyntax/json.rs
@@ -10,12 +10,13 @@
 // FIXME: spec the JSON output properly.
 
 use crate::source_map::{SourceMap, FilePathMapping};
+
 use errors::registry::Registry;
 use errors::{DiagnosticBuilder, SubDiagnostic, CodeSuggestion, SourceMapper};
 use errors::{DiagnosticId, Applicability};
 use errors::emitter::{Emitter, EmitterWriter};
 
-use syntax_pos::{self, MacroBacktrace, Span, SpanLabel, MultiSpan};
+use syntax_pos::{MacroBacktrace, Span, SpanLabel, MultiSpan};
 use rustc_data_structures::sync::{self, Lrc};
 use std::io::{self, Write};
 use std::vec;
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index 1634cbfc15629..7a16401828947 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -1,10 +1,10 @@
 use crate::ast::{self, Ident};
 use crate::source_map::{SourceMap, FilePathMapping};
-use errors::{Applicability, FatalError, Diagnostic, DiagnosticBuilder};
 use crate::parse::{token, ParseSess};
 use crate::symbol::{Symbol, keywords};
 
-use syntax_pos::{self, BytePos, CharPos, Pos, Span, NO_EXPANSION};
+use errors::{Applicability, FatalError, Diagnostic, DiagnosticBuilder};
+use syntax_pos::{BytePos, CharPos, Pos, Span, NO_EXPANSION};
 use core::unicode::property::Pattern_White_Space;
 
 use std::borrow::Cow;
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 1ac3d8ec78166..87ca883ef7ba9 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -3,7 +3,6 @@
 use crate::ast::{self, CrateConfig, NodeId};
 use crate::early_buffered_lints::{BufferedEarlyLint, BufferedEarlyLintId};
 use crate::source_map::{SourceMap, FilePathMapping};
-use errors::{FatalError, Level, Handler, ColorConfig, Diagnostic, DiagnosticBuilder};
 use crate::feature_gate::UnstableFeatures;
 use crate::parse::parser::Parser;
 use crate::symbol::Symbol;
@@ -11,6 +10,7 @@ use crate::tokenstream::{TokenStream, TokenTree};
 use crate::diagnostics::plugin::ErrorMap;
 use crate::print::pprust::token_to_string;
 
+use errors::{FatalError, Level, Handler, ColorConfig, Diagnostic, DiagnosticBuilder};
 use rustc_data_structures::sync::{Lrc, Lock};
 use syntax_pos::{Span, SourceFile, FileName, MultiSpan};
 use log::debug;
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 8db8c253bad45..3eacd61c318ef 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -33,7 +33,6 @@ use crate::ast::{RangeEnd, RangeSyntax};
 use crate::{ast, attr};
 use crate::ext::base::DummyResult;
 use crate::source_map::{self, SourceMap, Spanned, respan};
-use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
 use crate::parse::{self, SeqSep, classify, token};
 use crate::parse::lexer::{TokenAndSpan, UnmatchedBrace};
 use crate::parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
@@ -47,8 +46,9 @@ use crate::ThinVec;
 use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint};
 use crate::symbol::{Symbol, keywords};
 
+use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
 use rustc_target::spec::abi::{self, Abi};
-use syntax_pos::{self, Span, MultiSpan, BytePos, FileName};
+use syntax_pos::{Span, MultiSpan, BytePos, FileName};
 use log::{debug, trace};
 
 use std::borrow::Cow;
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs
index 6506546b3b2ef..56290fa771ba9 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -12,11 +12,10 @@ use std::vec;
 
 use log::debug;
 use smallvec::{smallvec, SmallVec};
-use syntax_pos::{self, DUMMY_SP, NO_EXPANSION, Span, SourceFile, BytePos};
+use syntax_pos::{DUMMY_SP, NO_EXPANSION, Span, SourceFile, BytePos};
 
 use crate::attr::{self, HasAttrs};
 use crate::source_map::{self, SourceMap, ExpnInfo, MacroAttribute, dummy_spanned, respan};
-use errors;
 use crate::config;
 use crate::entry::{self, EntryPointType};
 use crate::ext::base::{ExtCtxt, Resolver};
diff --git a/src/libsyntax/test_snippet.rs b/src/libsyntax/test_snippet.rs
index e9ea39b83d4cb..cf39090e1888b 100644
--- a/src/libsyntax/test_snippet.rs
+++ b/src/libsyntax/test_snippet.rs
@@ -1,7 +1,8 @@
 use crate::source_map::{SourceMap, FilePathMapping};
+use crate::with_globals;
+
 use errors::Handler;
 use errors::emitter::EmitterWriter;
-use crate::with_globals;
 
 use std::io;
 use std::io::prelude::*;
diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs
index 81fcdc4be2b3d..6aba4d83cd27c 100644
--- a/src/libsyntax_ext/deriving/custom.rs
+++ b/src/libsyntax_ext/deriving/custom.rs
@@ -1,7 +1,7 @@
-use errors::FatalError;
 use crate::proc_macro_impl::EXEC_STRATEGY;
 use crate::proc_macro_server;
 
+use errors::FatalError;
 use syntax::ast::{self, ItemKind, Attribute, Mac};
 use syntax::attr::{mark_used, mark_known};
 use syntax::source_map::Span;
diff --git a/src/libsyntax_ext/proc_macro_impl.rs b/src/libsyntax_ext/proc_macro_impl.rs
index 03290df0c72ae..f0fc6392cd73f 100644
--- a/src/libsyntax_ext/proc_macro_impl.rs
+++ b/src/libsyntax_ext/proc_macro_impl.rs
@@ -1,6 +1,6 @@
-use errors::FatalError;
 use crate::proc_macro_server;
 
+use errors::FatalError;
 use syntax::source_map::Span;
 use syntax::ext::base::{self, *};
 use syntax::tokenstream::TokenStream;

From c08b5ca4ad26250f6af17ba7e2938d9e694f2842 Mon Sep 17 00:00:00 2001
From: Taiki Endo <te316e89@gmail.com>
Date: Sun, 10 Feb 2019 15:27:59 +0900
Subject: [PATCH 23/24] Fix rebase fail

---
 src/librustc_resolve/error_reporting.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs
index 8300e691bbea4..0cabee71df9fb 100644
--- a/src/librustc_resolve/error_reporting.rs
+++ b/src/librustc_resolve/error_reporting.rs
@@ -1,5 +1,6 @@
 use std::cmp::Reverse;
 
+use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
 use log::debug;
 use rustc::hir::def::*;
 use rustc::hir::def::Namespace::*;
@@ -9,7 +10,6 @@ use syntax::ast::{ExprKind};
 use syntax::symbol::keywords;
 use syntax_pos::Span;
 
-use crate::errors::{Applicability, DiagnosticBuilder, DiagnosticId};
 use crate::macros::ParentScope;
 use crate::resolve_imports::ImportResolver;
 use crate::{import_candidate_to_enum_paths, is_self_type, is_self_value, path_names_to_string};

From 3a9d171b0a118d8f0ecda1bf44775ec4ba9bb79d Mon Sep 17 00:00:00 2001
From: Michael Woerister <michaelwoerister@posteo>
Date: Tue, 12 Feb 2019 17:17:05 +0100
Subject: [PATCH 24/24] Fix some rebasing fallout regarding xLTO.

---
 src/librustc_codegen_ssa/back/linker.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs
index 4b34bf704d588..765b0e91d921a 100644
--- a/src/librustc_codegen_ssa/back/linker.rs
+++ b/src/librustc_codegen_ssa/back/linker.rs
@@ -1207,6 +1207,6 @@ impl<'a> Linker for PtxLinker<'a> {
     fn group_end(&mut self) {
     }
 
-    fn cross_lang_lto(&mut self) {
+    fn linker_plugin_lto(&mut self) {
     }
 }